From ee7254d0623c4dc7ed9ef4e8e36292461097676a Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Thu, 22 Aug 2024 13:56:58 +0200 Subject: [PATCH 01/20] (hub): draft impl of loosened constraint on explicit groupMint --- src/hub/Hub.sol | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index b0ce135..8708ee9 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -425,7 +425,7 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { for (uint256 i = 0; i < _collateralAvatars.length; i++) { collateral[i] = toTokenId(_collateralAvatars[i]); } - _groupMint(msg.sender, msg.sender, _group, collateral, _amounts, _data); + _groupMint(msg.sender, msg.sender, _group, collateral, _amounts, _data, true); } /** @@ -636,6 +636,8 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { * @param _collateral array of (personal or group) avatar addresses to be used as collateral * @param _amounts array of amounts of collateral to be used for minting * @param _data (optional) additional data to be passed to the mint policy, treasury and minter + * @param explicitGroupMint boolean indicating whether the group mint is called explicitly from the public groupMint function + * or implicitly from operateFlowMatrix */ function _groupMint( address _sender, @@ -643,7 +645,8 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { address _group, uint256[] memory _collateral, uint256[] memory _amounts, - bytes memory _data + bytes memory _data, + bool explicitGroupMint ) internal { if (_collateral.length != _amounts.length) { // Collateral and amount arrays must have equal length. @@ -666,9 +669,16 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // _groupMint is only called from the public groupMint function, // or from operateFlowMatrix, and both ensure the collateral ids are derived // from a registered address, so we can cast here without checking valid registration - if (!isPermittedFlow(_group, _validateAddressFromId(_collateral[i], 2))) { - // Group does not trust collateral, or flow edge is not permitted - revert CirclesHubFlowEdgeIsNotPermitted(_group, _collateral[i], 0); + if (!explicitGroupMint) { + if (!isPermittedFlow(_group, _validateAddressFromId(_collateral[i], 2))) { + // Group does not trust collateral, or flow edge is not permitted + revert CirclesHubFlowEdgeIsNotPermitted(_group, _collateral[i], 0); + } + } else { + if (!isTrusted(_group, _validateAddressFromId(_collateral[i], 3))) { + // Group does not trust collateral. + revert CirclesHubFlowEdgeIsNotPermitted(_group, _collateral[i], 0); + } } if (_amounts[i] == 0) { @@ -846,7 +856,8 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { to, // group; for triggering group mint, to == the group to mint for ids, // collateral amounts, // amounts - "" // path-based group mints never send data to the mint policy + "", // path-based group mints never send data to the mint policy + false ); } From 7e212a2835f4fbda756fd4817ebd6d4e52ed9021 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Thu, 22 Aug 2024 14:03:31 +0200 Subject: [PATCH 02/20] (hub): improve readability of groupmint logic, explicit collateral or implicit --- src/hub/Hub.sol | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index 8708ee9..e198573 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -666,19 +666,17 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // so it suffices to check that all amounts are non-zero during summing. uint256 sumAmounts = 0; for (uint256 i = 0; i < _amounts.length; i++) { - // _groupMint is only called from the public groupMint function, - // or from operateFlowMatrix, and both ensure the collateral ids are derived - // from a registered address, so we can cast here without checking valid registration - if (!explicitGroupMint) { - if (!isPermittedFlow(_group, _validateAddressFromId(_collateral[i], 2))) { - // Group does not trust collateral, or flow edge is not permitted - revert CirclesHubFlowEdgeIsNotPermitted(_group, _collateral[i], 0); - } - } else { - if (!isTrusted(_group, _validateAddressFromId(_collateral[i], 3))) { - // Group does not trust collateral. - revert CirclesHubFlowEdgeIsNotPermitted(_group, _collateral[i], 0); - } + address collateralAvatar = _validateAddressFromId(_collateral[i], 1); + + // if the group mint is called explicitly, check the group trusts the collateral + // otherwise if the group mint is called implicitly over operateFlowMatrix, + // check the flow edge is permitted + bool isValidCollateral = + explicitGroupMint ? isTrusted(_group, collateralAvatar) : isPermittedFlow(_group, collateralAvatar); + + if (!isValidCollateral) { + // Group does not trust collateral, or flow edge is not permitted + revert CirclesHubFlowEdgeIsNotPermitted(_group, _collateral[i], 0); } if (_amounts[i] == 0) { From 7be51d34e075883e008a4d9ab9849a8e875092c9 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Mon, 26 Aug 2024 16:35:45 +0200 Subject: [PATCH 03/20] (hub): revert patch2: ie put back disabling consented flow, but exceeds compile size, so doesn't work --- src/hub/Hub.sol | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index e198573..ac70ee0 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -39,6 +39,11 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { */ address private constant SENTINEL = address(0x1); + /** + * @dev advanced flag to indicate whether avatar disables consented flow + */ + bytes32 private constant ADVANCED_FLAG_DISABLE_CONSENTEDFLOW = bytes32(uint256(1)); + // State variables /** @@ -111,6 +116,13 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { */ mapping(address => mapping(address => TrustMarker)) public trustMarkers; + /** + * @notice Advanced usage flags for avatar. Only the least significant bit is used + * by the Circles protocol itself for consented flow behaviour, the remaining bits + * are reserved for future community-proposed extensions. + */ + mapping(address => bytes32) public advancedUsageFlags; + // Events event RegisterHuman(address indexed avatar); @@ -574,6 +586,19 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { _matchNettedFlows(streamsNettedFlow, matrixNettedFlow); } + /** + * @notice Set the advanced usage flag for the caller's avatar. + * @param _flag advanced usage flags combination to set + */ + function setAdvancedUsageFlag(bytes32 _flag) external { + if (avatars[msg.sender] == address(0)) { + // Only registered avatars can set advanced usage flags. + revert CirclesAvatarMustBeRegistered(msg.sender, 3); + } + + advancedUsageFlags[msg.sender] = _flag; + } + // Public functions /** @@ -612,9 +637,11 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { } /** - * @notice Returns true if the flow to the receiver is permitted. + * @notice Returns true if the flow to the receiver is permitted. This function is called only + * by the operateFlowMatrix function to check whether the flow edge is permitted. * The receiver must trust the Circles being sent, and the Circles avatar associated with - * the Circles must trust the receiver. + * the Circles must trust the receiver. Unless the Circles avatar concerned has opted out of + * consented flow, in which case the flow is permitted once the receiver trusts the Circles. * @param _to Address of the receiver * @param _circlesAvatar Address of the Circles avatar of the Circles being sent * @return permitted true if the flow is permitted, false otherwise @@ -622,7 +649,11 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { function isPermittedFlow(address _to, address _circlesAvatar) public view returns (bool) { // if receiver does not trust the Circles being sent, then the flow is not permitted regardless if (uint256(trustMarkers[_to][_circlesAvatar].expiry) < block.timestamp) return false; - // however, consented flow also requires bi-directional trust from center to receiver + // if the advanced usage flag disables consented flow, then the uni-directional trust is sufficient + if (advancedUsageFlags[_circlesAvatar] & ADVANCED_FLAG_DISABLE_CONSENTEDFLOW != bytes32(0)) { + return true; + } + // however, consented flow also requires bi-directional trust from center (minter) to receiver return uint256(trustMarkers[_circlesAvatar][_to].expiry) >= block.timestamp; } From f592ae46b4443b5d2d19aa582763fb2705f25d8d Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Mon, 26 Aug 2024 16:53:16 +0200 Subject: [PATCH 04/20] (hub): remove public name and symbol (because not defined in ERC1155) to free compile size --- src/hub/Hub.sol | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index ac70ee0..3b9cf8e 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -46,17 +46,17 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // State variables - /** - * @notice The global name of Circles. - * todo, change this to "Circles" for the production deployment - */ - string public name = "Rings"; - - /** - * @notice The global symbol ticker for Circles. - * todo, change this to "CRC" for the production deployment - */ - string public symbol = "RING"; + // /** + // * @notice The global name of Circles. + // * todo, change this to "Circles" for the production deployment + // */ + // string public name = "Rings"; + + // /** + // * @notice The global symbol ticker for Circles. + // * todo, change this to "CRC" for the production deployment + // */ + // string public symbol = "RING"; /** * @notice The Hub v1 contract address. From ab2fafaaf99a33b76db6f242108bdeb927ff134c Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Mon, 26 Aug 2024 21:41:30 +0200 Subject: [PATCH 05/20] (hub): change definition of consented flow to: Minter <-T- Receiver <-T- Sender --- src/hub/Hub.sol | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index 3b9cf8e..87e07c0 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -639,22 +639,23 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { /** * @notice Returns true if the flow to the receiver is permitted. This function is called only * by the operateFlowMatrix function to check whether the flow edge is permitted. - * The receiver must trust the Circles being sent, and the Circles avatar associated with - * the Circles must trust the receiver. Unless the Circles avatar concerned has opted out of + * The receiver must trust the Circles being sent, and the sender must trust the receiver. + * Unless the sender avatar concerned has opted out of * consented flow, in which case the flow is permitted once the receiver trusts the Circles. + * @param _from Address of the sender * @param _to Address of the receiver * @param _circlesAvatar Address of the Circles avatar of the Circles being sent * @return permitted true if the flow is permitted, false otherwise */ - function isPermittedFlow(address _to, address _circlesAvatar) public view returns (bool) { + function isPermittedFlow(address _from, address _to, address _circlesAvatar) public view returns (bool) { // if receiver does not trust the Circles being sent, then the flow is not permitted regardless if (uint256(trustMarkers[_to][_circlesAvatar].expiry) < block.timestamp) return false; // if the advanced usage flag disables consented flow, then the uni-directional trust is sufficient - if (advancedUsageFlags[_circlesAvatar] & ADVANCED_FLAG_DISABLE_CONSENTEDFLOW != bytes32(0)) { + if (advancedUsageFlags[_from] & ADVANCED_FLAG_DISABLE_CONSENTEDFLOW != bytes32(0)) { return true; } - // however, consented flow also requires bi-directional trust from center (minter) to receiver - return uint256(trustMarkers[_circlesAvatar][_to].expiry) >= block.timestamp; + // however, consented flow also requires sender to trust the receiver + return uint256(trustMarkers[_from][_to].expiry) >= block.timestamp; } // Internal functions @@ -702,8 +703,9 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // if the group mint is called explicitly, check the group trusts the collateral // otherwise if the group mint is called implicitly over operateFlowMatrix, // check the flow edge is permitted - bool isValidCollateral = - explicitGroupMint ? isTrusted(_group, collateralAvatar) : isPermittedFlow(_group, collateralAvatar); + bool isValidCollateral = explicitGroupMint + ? isTrusted(_group, collateralAvatar) + : isPermittedFlow(_sender, _group, collateralAvatar); if (!isValidCollateral) { // Group does not trust collateral, or flow edge is not permitted @@ -795,12 +797,13 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // index + 1: sender coordinate // index + 2: receiver coordinate address circlesId = _flowVertices[_coordinates[index]]; + address from = _flowVertices[_coordinates[index + 1]]; address to = _flowVertices[_coordinates[index + 2]]; int256 flow = int256(uint256(_flow[i].amount)); // check the receiver trusts the Circles being sent - // and that the center trusts the receiver (unless center opt-ed out) - if (!isPermittedFlow(to, circlesId)) { + // and that the sender trusts the receiver (unless sender opt-ed out of consented flow) + if (!isPermittedFlow(from, to, circlesId)) { // Flow edge is not permitted. revert CirclesHubFlowEdgeIsNotPermitted(to, toTokenId(circlesId), 1); } From f0f946ebcb7c33b445492fa49c9f38db10bb4237 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Mon, 26 Aug 2024 23:07:22 +0200 Subject: [PATCH 06/20] (hub): align register and invite human events; also emit for migration flow; reduces compile size within limits --- src/hub/Hub.sol | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index 87e07c0..b278985 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -126,7 +126,7 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // Events event RegisterHuman(address indexed avatar); - event InviteHuman(address indexed inviter, address indexed invited); + // event InviteHuman(address indexed inviter, address indexed invited); event RegisterOrganization(address indexed organization, string name); event RegisterGroup( address indexed group, address indexed mint, address indexed treasury, string name, string symbol @@ -248,8 +248,6 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { if (_metadataDigest != bytes32(0)) { nameRegistry.setMetadataDigest(msg.sender, _metadataDigest); } - - emit RegisterHuman(msg.sender); } /** @@ -278,8 +276,6 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // set trust to indefinite future, but avatar can edit this later _trust(msg.sender, _human, INDEFINITE_FUTURE); - - emit InviteHuman(msg.sender, _human); } /** @@ -437,7 +433,7 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { for (uint256 i = 0; i < _collateralAvatars.length; i++) { collateral[i] = toTokenId(_collateralAvatars[i]); } - _groupMint(msg.sender, msg.sender, _group, collateral, _amounts, _data, true); + _groupMint(msg.sender, msg.sender, _group, collateral, _amounts, _data); } /** @@ -668,8 +664,6 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { * @param _collateral array of (personal or group) avatar addresses to be used as collateral * @param _amounts array of amounts of collateral to be used for minting * @param _data (optional) additional data to be passed to the mint policy, treasury and minter - * @param explicitGroupMint boolean indicating whether the group mint is called explicitly from the public groupMint function - * or implicitly from operateFlowMatrix */ function _groupMint( address _sender, @@ -677,8 +671,7 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { address _group, uint256[] memory _collateral, uint256[] memory _amounts, - bytes memory _data, - bool explicitGroupMint + bytes memory _data ) internal { if (_collateral.length != _amounts.length) { // Collateral and amount arrays must have equal length. @@ -700,12 +693,9 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { for (uint256 i = 0; i < _amounts.length; i++) { address collateralAvatar = _validateAddressFromId(_collateral[i], 1); - // if the group mint is called explicitly, check the group trusts the collateral - // otherwise if the group mint is called implicitly over operateFlowMatrix, - // check the flow edge is permitted - bool isValidCollateral = explicitGroupMint - ? isTrusted(_group, collateralAvatar) - : isPermittedFlow(_sender, _group, collateralAvatar); + // check the group trusts the collateral + // and if the sender has opted into consented flow, the sender must also trust the the group + bool isValidCollateral = isPermittedFlow(_sender, _group, collateralAvatar); if (!isValidCollateral) { // Group does not trust collateral, or flow edge is not permitted @@ -888,8 +878,7 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { to, // group; for triggering group mint, to == the group to mint for ids, // collateral amounts, // amounts - "", // path-based group mints never send data to the mint policy - false + "" // path-based group mints never send data to the mint policy ); } @@ -993,6 +982,8 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // trust self indefinitely, cannot be altered later _trust(_human, _human, INDEFINITE_FUTURE); + emit RegisterHuman(_human); + return v1CirclesStatus; } From 838b1cb4e002aa014465899df5c5e0404114a738 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Mon, 26 Aug 2024 23:14:06 +0200 Subject: [PATCH 07/20] (hub): change default behaviour to NOT enabling consented flow --- src/hub/Hub.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index b278985..350bf37 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -40,9 +40,9 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { address private constant SENTINEL = address(0x1); /** - * @dev advanced flag to indicate whether avatar disables consented flow + * @dev advanced flag to indicate whether avatar enables consented flow */ - bytes32 private constant ADVANCED_FLAG_DISABLE_CONSENTEDFLOW = bytes32(uint256(1)); + bytes32 private constant ADVANCED_FLAG_ENABLE_CONSENTEDFLOW = bytes32(uint256(1)); // State variables @@ -646,8 +646,9 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { function isPermittedFlow(address _from, address _to, address _circlesAvatar) public view returns (bool) { // if receiver does not trust the Circles being sent, then the flow is not permitted regardless if (uint256(trustMarkers[_to][_circlesAvatar].expiry) < block.timestamp) return false; - // if the advanced usage flag disables consented flow, then the uni-directional trust is sufficient - if (advancedUsageFlags[_from] & ADVANCED_FLAG_DISABLE_CONSENTEDFLOW != bytes32(0)) { + // if the advanced usage flag does not enables consented flow, + // then the uni-directional trust is sufficient, ie. no consented flow applies for sender + if (advancedUsageFlags[_from] & ADVANCED_FLAG_ENABLE_CONSENTEDFLOW == bytes32(0)) { return true; } // however, consented flow also requires sender to trust the receiver From d57752019cf607fbad26a6eef89e67464e3c7258 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Mon, 26 Aug 2024 23:15:33 +0200 Subject: [PATCH 08/20] (hub): remove attempt for name, symbol now for good; we wont have room for it --- src/hub/Hub.sol | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index 350bf37..be3cbd5 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -46,18 +46,6 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // State variables - // /** - // * @notice The global name of Circles. - // * todo, change this to "Circles" for the production deployment - // */ - // string public name = "Rings"; - - // /** - // * @notice The global symbol ticker for Circles. - // * todo, change this to "CRC" for the production deployment - // */ - // string public symbol = "RING"; - /** * @notice The Hub v1 contract address. */ From e68f8fa53f455def602b184b014c69db0f9b7c3e Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Mon, 26 Aug 2024 23:20:13 +0200 Subject: [PATCH 09/20] (hub): update comment on isPermittedFlow() for default behaviour of no-consented flow --- src/hub/Hub.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index be3cbd5..f9636fb 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -621,11 +621,11 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { } /** - * @notice Returns true if the flow to the receiver is permitted. This function is called only - * by the operateFlowMatrix function to check whether the flow edge is permitted. - * The receiver must trust the Circles being sent, and the sender must trust the receiver. - * Unless the sender avatar concerned has opted out of - * consented flow, in which case the flow is permitted once the receiver trusts the Circles. + * @notice Returns true if the flow to the receiver is permitted. By default avatars don't have + * consented flow enabled, so then this function is equivalent to isTrusted(). This function is called + * to check whether the flow edge is permitted (either along a path's flow edge, or upon groupMint). + * If the sender avatar has enabled consented flow for the Circles balances they own, + * then the receiver must trust the Circles being sent, and the sender must trust the receiver. * @param _from Address of the sender * @param _to Address of the receiver * @param _circlesAvatar Address of the Circles avatar of the Circles being sent From 1303e44b5ab513c449e6b52ac36df11f21478fa2 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Mon, 26 Aug 2024 23:21:33 +0200 Subject: [PATCH 10/20] (hub): remove commented out event definition InviteHuman --- src/hub/Hub.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index f9636fb..d52dd40 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -114,7 +114,6 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // Events event RegisterHuman(address indexed avatar); - // event InviteHuman(address indexed inviter, address indexed invited); event RegisterOrganization(address indexed organization, string name); event RegisterGroup( address indexed group, address indexed mint, address indexed treasury, string name, string symbol From c259ceeef856ca23b5ddcf68e021f400ba2033b6 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Mon, 26 Aug 2024 23:23:55 +0200 Subject: [PATCH 11/20] (hub): anotehr comment to update for default behaviour now NOT being consented flow --- src/hub/Hub.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index d52dd40..c5be32e 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -780,7 +780,7 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { int256 flow = int256(uint256(_flow[i].amount)); // check the receiver trusts the Circles being sent - // and that the sender trusts the receiver (unless sender opt-ed out of consented flow) + // and if the sender has enabled consented flow, also check that the sender trusts the receiver if (!isPermittedFlow(from, to, circlesId)) { // Flow edge is not permitted. revert CirclesHubFlowEdgeIsNotPermitted(to, toTokenId(circlesId), 1); From c18e09fc67d1887e7807e81d627eb922a7ae7caa Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Tue, 27 Aug 2024 14:10:11 +0200 Subject: [PATCH 12/20] (hub): recursive consented flow MRS model --- src/hub/Hub.sol | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index c5be32e..0c91d11 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -624,7 +624,8 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { * consented flow enabled, so then this function is equivalent to isTrusted(). This function is called * to check whether the flow edge is permitted (either along a path's flow edge, or upon groupMint). * If the sender avatar has enabled consented flow for the Circles balances they own, - * then the receiver must trust the Circles being sent, and the sender must trust the receiver. + * then the receiver must trust the Circles being sent, and the sender must trust the receiver, + * and to preserve the protection recursively the receiver themselves must have consented flow enabled. * @param _from Address of the sender * @param _to Address of the receiver * @param _circlesAvatar Address of the Circles avatar of the Circles being sent @@ -638,8 +639,12 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { if (advancedUsageFlags[_from] & ADVANCED_FLAG_ENABLE_CONSENTEDFLOW == bytes32(0)) { return true; } - // however, consented flow also requires sender to trust the receiver - return uint256(trustMarkers[_from][_to].expiry) >= block.timestamp; + // however, recursive consented flow also requires sender to trust the receiver + // and for that receiver themselves to have consented flow enabled + return ( + uint256(trustMarkers[_from][_to].expiry) >= block.timestamp + && advancedUsageFlags[_to] & ADVANCED_FLAG_ENABLE_CONSENTEDFLOW != bytes32(0) + ); } // Internal functions From a1876f5781a7a1e75fdb0e84651c4a40a52523f3 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Wed, 28 Aug 2024 15:41:31 +0100 Subject: [PATCH 13/20] (hub): change welcome bonus to 48 CRC (2 days) --- src/hub/Hub.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index 0c91d11..9bf5155 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -27,7 +27,7 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { /** * @dev Welcome bonus for new avatars invited to Circles. Set to 50 Circles. */ - uint256 private constant WELCOME_BONUS = 50 * EXA; + uint256 private constant WELCOME_BONUS = 48 * EXA; /** * @dev The cost of an invitation for a new avatar, paid in personal Circles burnt, set to 100 Circles. From ef9c1f0f01056aab7b019db7beb1cef1d2648857 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Wed, 28 Aug 2024 16:56:30 +0100 Subject: [PATCH 14/20] (NameRegistry): remove stale comment --- src/names/NameRegistry.sol | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/names/NameRegistry.sol b/src/names/NameRegistry.sol index 7200332..fff400a 100644 --- a/src/names/NameRegistry.sol +++ b/src/names/NameRegistry.sol @@ -27,11 +27,6 @@ contract NameRegistry is Base58Converter, INameRegistry, INameRegistryErrors, IC */ string public constant DEFAULT_CIRCLES_SYMBOL = "RING"; - // /** - // * @dev The IPFS protocol prefix for cid v0 resolution - // */ - // string private constant IPFS_PROTOCOL = "ipfs://Qm"; - // State variables /** From c4b04d06abac995beda8cfb0ff494ab41b2b99da Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Wed, 28 Aug 2024 18:44:42 +0100 Subject: [PATCH 15/20] (demurrage): make conversion helper functions two-way inflationary and back --- script/deployments/package.json | 2 +- src/circles/BatchedDemurrage.sol | 47 ++++++++++++++++++++++++++ src/circles/Demurrage.sol | 23 ++++++------- src/circles/InflationaryOperator.sol | 4 +-- src/lift/ERC20InflationaryBalances.sol | 4 +-- 5 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 src/circles/BatchedDemurrage.sol diff --git a/script/deployments/package.json b/script/deployments/package.json index e9f010b..1ab192d 100644 --- a/script/deployments/package.json +++ b/script/deployments/package.json @@ -1,6 +1,6 @@ { "name": "deploy-circles", - "version": "rc-0.3.5-alpha", + "version": "rc-0.3.6-alpha", "type": "module", "dependencies": { "dotenv": "^16.4.5", diff --git a/src/circles/BatchedDemurrage.sol b/src/circles/BatchedDemurrage.sol new file mode 100644 index 0000000..319824d --- /dev/null +++ b/src/circles/BatchedDemurrage.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity >=0.8.24; + +import "./Demurrage.sol"; + +contract BatchedDemurrage is Demurrage { + /** + * @notice Converts a batch of inflationary values to demurrage values for a given day since inflation_day_zero. + * @param _inflationaryValues Batch of inflationary values to convert to demurrage values. + * @param _day Day since inflation_day_zero to convert the inflationary values to demurrage values. + */ + function convertBatchInflationaryToDemurrageValues(uint256[] memory _inflationaryValues, uint64 _day) + public + pure + returns (uint256[] memory) + { + // calculate the demurrage value by multiplying the value by GAMMA^days + // note: same remark on precision as in convertInflationaryToDemurrageValue + int128 r = Math64x64.pow(GAMMA_64x64, uint256(_day)); + uint256[] memory demurrageValues = new uint256[](_inflationaryValues.length); + for (uint256 i = 0; i < _inflationaryValues.length; i++) { + demurrageValues[i] = Math64x64.mulu(r, _inflationaryValues[i]); + } + return demurrageValues; + } + + /** + * @notice Converts a batch of demurrage values to inflationary values for a given day since inflation_day_zero. + * @param _demurrageValues Batch of demurrage values to convert to inflationary values. + * @param _dayUpdated Day since inflation_day_zero to convert the demurrage values to inflationary values. + */ + function convertBatchDemurrageToInflationaryValues(uint256[] memory _demurrageValues, uint64 _dayUpdated) + public + pure + returns (uint256[] memory) + { + // calculate the inflationary value by dividing the value by GAMMA^days + // note: GAMMA < 1, so dividing by a power of it, returns a bigger number, + // so the numerical imprecision is introduced the least significant bits. + int128 f = Math64x64.pow(BETA_64x64, uint256(_dayUpdated)); + uint256[] memory inflationaryValues = new uint256[](_demurrageValues.length); + for (uint256 i = 0; i < _demurrageValues.length; i++) { + inflationaryValues[i] = Math64x64.mulu(f, _demurrageValues[i]); + } + return inflationaryValues; + } +} diff --git a/src/circles/Demurrage.sol b/src/circles/Demurrage.sol index 76dd014..92ed82f 100644 --- a/src/circles/Demurrage.sol +++ b/src/circles/Demurrage.sol @@ -192,23 +192,20 @@ contract Demurrage is ICirclesDemurrageErrors { } /** - * @notice Converts a batch of inflationary values to demurrage values for a given day since inflation_day_zero. - * @param _inflationaryValues Batch of inflationary values to convert to demurrage values. - * @param _day Day since inflation_day_zero to convert the inflationary values to demurrage values. + * @notice Converts a demurrage value to an inflationary value for a given day since inflation_day_zero. + * @param _demurrageValue Demurrage value to convert to inflationary value + * @param _dayUpdated The day the demurrage value was last updated since inflation_day_zero */ - function convertBatchInflationaryToDemurrageValues(uint256[] memory _inflationaryValues, uint64 _day) + function convertDemurrageToInflationaryValue(uint256 _demurrageValue, uint64 _dayUpdated) public pure - returns (uint256[] memory) + returns (uint256) { - // calculate the demurrage value by multiplying the value by GAMMA^days - // note: same remark on precision as in convertInflationaryToDemurrageValue - int128 r = Math64x64.pow(GAMMA_64x64, uint256(_day)); - uint256[] memory demurrageValues = new uint256[](_inflationaryValues.length); - for (uint256 i = 0; i < _inflationaryValues.length; i++) { - demurrageValues[i] = Math64x64.mulu(r, _inflationaryValues[i]); - } - return demurrageValues; + // calculate the inflationary value by dividing the value by GAMMA^days + // note: GAMMA < 1, so dividing by a power of it, returns a bigger number, + // so the numerical imprecision is introduced in the least significant bits. + int128 f = Math64x64.pow(BETA_64x64, uint256(_dayUpdated)); + return Math64x64.mulu(f, _demurrageValue); } // Internal functions diff --git a/src/circles/InflationaryOperator.sol b/src/circles/InflationaryOperator.sol index 7097679..1105940 100644 --- a/src/circles/InflationaryOperator.sol +++ b/src/circles/InflationaryOperator.sol @@ -2,9 +2,9 @@ pragma solidity >=0.8.24; import "../hub/IHub.sol"; -import "./Demurrage.sol"; +import "./BatchedDemurrage.sol"; -contract InflationaryCirclesOperator is Demurrage { +contract InflationaryCirclesOperator is BatchedDemurrage { // Storage IHubV2 public hub; diff --git a/src/lift/ERC20InflationaryBalances.sol b/src/lift/ERC20InflationaryBalances.sol index 297d44f..bb04e92 100644 --- a/src/lift/ERC20InflationaryBalances.sol +++ b/src/lift/ERC20InflationaryBalances.sol @@ -2,10 +2,10 @@ pragma solidity >=0.8.24; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "../circles/Demurrage.sol"; +import "../circles/BatchedDemurrage.sol"; import "./ERC20Permit.sol"; -contract ERC20InflationaryBalances is ERC20Permit, Demurrage, IERC20 { +contract ERC20InflationaryBalances is ERC20Permit, BatchedDemurrage, IERC20 { // Constants uint8 internal constant EXTENDED_ACCURACY_BITS = 64; From 899e738054d90e88d786a7ede696043155b47fd4 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Wed, 28 Aug 2024 19:25:49 +0100 Subject: [PATCH 16/20] (hub): allow self-registration always IFF the v1 token was stopped before the end of the invitation period --- src/errors/Errors.sol | 4 +-- src/hub/Hub.sol | 54 ++++++++++++++++++++++------------------ src/migration/IToken.sol | 2 ++ 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/errors/Errors.sol b/src/errors/Errors.sol index ffd15b3..155d4d0 100644 --- a/src/errors/Errors.sol +++ b/src/errors/Errors.sol @@ -2,9 +2,7 @@ pragma solidity >=0.8.24; interface IHubErrors { - error CirclesHubOnlyDuringBootstrap(uint8 code); - - error CirclesHubRegisterAvatarV1MustBeStopped(address avatar, uint8 code); + error CirclesHubRegisterAvatarV1MustBeStoppedBeforeEndOfInvitationPeriod(address avatar, uint8 code); error CirclesHubAvatarAlreadyRegistered(address avatar, uint8 code); diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index 9bf5155..1c41bc7 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -129,16 +129,6 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // Modifiers - /** - * Modifier to check if the current time is during the bootstrap period. - */ - modifier onlyDuringBootstrap(uint8 _code) { - if (block.timestamp > invitationOnlyTime) { - revert CirclesHubOnlyDuringBootstrap(_code); - } - _; - } - /** * Modifier to check if the caller is the migration contract. */ @@ -220,15 +210,21 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { /** * @notice Register human allows to register an avatar for a human, - * if they have a stopped v1 Circles contract, during the bootstrap period. + * if they have a stopped v1 Circles contract, that has been stopped + * before the end of the invitation period. * @param _metadataDigest (optional) sha256 metadata digest for the avatar metadata * should follow ERC1155 metadata standard. */ - function registerHuman(bytes32 _metadataDigest) external onlyDuringBootstrap(0) { + function registerHuman(bytes32 _metadataDigest) external { // only available for v1 users with stopped v1 mint, for initial bootstrap period - address v1CirclesStatus = _registerHuman(msg.sender); + (address v1CirclesStatus, uint256 v1LastTouched) = _registerHuman(msg.sender); + // check if v1 Circles exists and has been stopped if (v1CirclesStatus != CIRCLES_STOPPED_V1) { - revert CirclesHubRegisterAvatarV1MustBeStopped(msg.sender, 0); + revert CirclesHubRegisterAvatarV1MustBeStoppedBeforeEndOfInvitationPeriod(msg.sender, 0); + } + // if it has been stopped, did it stop before the end of the invitation period? + if (v1LastTouched >= invitationOnlyTime) { + revert CirclesHubRegisterAvatarV1MustBeStoppedBeforeEndOfInvitationPeriod(msg.sender, 1); } // store the metadata digest for the avatar metadata @@ -250,6 +246,9 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { } // register the invited human; reverts if they already exist + // it checks the status of the avatar in v1, but regardless of the status + // we can proceed to register the avatar in v2 (they might not be able to mint yet + // if they have not stopped their v1 contract) _registerHuman(_human); if (block.timestamp > invitationOnlyTime) { @@ -961,13 +960,13 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { * Additionally set the trust to self indefinitely. * @param _human address of the human to be registered */ - function _registerHuman(address _human) internal returns (address v1CirclesStatus) { + function _registerHuman(address _human) internal returns (address v1CirclesStatus, uint256 v1LastTouched) { // insert avatar into linked list; reverts if it already exists _insertAvatar(_human); // set the last mint time to the current timestamp for invited human // and register the v1 Circles contract status - v1CirclesStatus = _avatarV1CirclesStatus(_human); + (v1CirclesStatus, v1LastTouched) = _avatarV1CirclesStatus(_human); MintTime storage mintTime = mintTimes[_human]; mintTime.mintV1Status = v1CirclesStatus; mintTime.lastMintTime = uint96(block.timestamp); @@ -977,7 +976,7 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { emit RegisterHuman(_human); - return v1CirclesStatus; + return (v1CirclesStatus, v1LastTouched); } /** @@ -1058,29 +1057,36 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // check if v1 Circles is known to be stopped if (mintTimes[_human].mintV1Status != CIRCLES_STOPPED_V1) { // if v1 Circles is not known to be stopped, check the status - address v1MintStatus = _avatarV1CirclesStatus(_human); + (address v1MintStatus,) = _avatarV1CirclesStatus(_human); _updateMintV1Status(_human, v1MintStatus); } } /** - * Checks the status of an avatar's Circles in the Hub v1 contract, + * @dev Checks the status of an avatar's Circles in the Hub v1 contract, * and returns the address of the Circles if it exists and is not stopped. * Else, it returns the zero address if no Circles exist, * and it returns the address CIRCLES_STOPPED_V1 (0x1) if the Circles contract is stopped. + * If a Circles contract exists, it also returns the last touched time of the Circles v1 token. * @param _avatar avatar address for which to check registration in Hub v1 + * @return address of the Circles contract if it exists and is not stopped, or zero address if no Circles exist + * or CIRCLES_STOPPED_V1 if the Circles contract is stopped. + * Additionally, return the last touched time of the Circles v1 token (ie. the last time it minted CRC), + * if the token exists, or zero if it does not. */ - function _avatarV1CirclesStatus(address _avatar) internal view returns (address) { + function _avatarV1CirclesStatus(address _avatar) internal view returns (address, uint256) { address circlesV1 = hubV1.userToToken(_avatar); // no token exists in Hub v1, so return status is zero address - if (circlesV1 == address(0)) return address(0); + if (circlesV1 == address(0)) return (address(0), uint256(0)); + // get the last touched time of the Circles v1 token + uint256 lastTouched = ITokenV1(circlesV1).lastTouched(); // return the status of the token if (ITokenV1(circlesV1).stopped()) { - // return the stopped status of the Circles contract - return CIRCLES_STOPPED_V1; + // return the stopped status of the Circles contract, and the last touched time + return (CIRCLES_STOPPED_V1, lastTouched); } else { // return the address of the Circles contract if it exists and is not stopped - return circlesV1; + return (circlesV1, lastTouched); } } diff --git a/src/migration/IToken.sol b/src/migration/IToken.sol index a564fc4..11554f0 100644 --- a/src/migration/IToken.sol +++ b/src/migration/IToken.sol @@ -15,4 +15,6 @@ interface ITokenV1 is IERC20 { function stopped() external view returns (bool); function update() external; + + function lastTouched() external view returns (uint256); } From d9214b6d272394a3aacf12edc54c4dbc436f84ac Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Wed, 28 Aug 2024 23:24:30 +0100 Subject: [PATCH 17/20] (hub): change the invite flow for humans to use trust as extended invitation --- src/hub/Hub.sol | 93 +++++++++++++++------------- src/operators/SignedPathOperator.sol | 7 --- test/hub/V1MintStatusUpdate.t.sol | 10 ++- 3 files changed, 58 insertions(+), 52 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index 1c41bc7..7612c48 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -212,56 +212,62 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { * @notice Register human allows to register an avatar for a human, * if they have a stopped v1 Circles contract, that has been stopped * before the end of the invitation period. + * Otherwise the caller must have been invited by an already registered human avatar. + * Humans can invite someone by trusting their address ahead of this call. + * After the invitation period, the inviter must burn the invitation cost, and the + * newly registered human will receive the welcome bonus. + * @param _inviter address of the inviter, who must have trusted the caller ahead of this call. + * If the inviter is zero, the caller can self-register if they have a stopped v1 Circles contract + * (stopped before the end of the invitation period). * @param _metadataDigest (optional) sha256 metadata digest for the avatar metadata * should follow ERC1155 metadata standard. */ - function registerHuman(bytes32 _metadataDigest) external { - // only available for v1 users with stopped v1 mint, for initial bootstrap period - (address v1CirclesStatus, uint256 v1LastTouched) = _registerHuman(msg.sender); - // check if v1 Circles exists and has been stopped - if (v1CirclesStatus != CIRCLES_STOPPED_V1) { - revert CirclesHubRegisterAvatarV1MustBeStoppedBeforeEndOfInvitationPeriod(msg.sender, 0); - } - // if it has been stopped, did it stop before the end of the invitation period? - if (v1LastTouched >= invitationOnlyTime) { - revert CirclesHubRegisterAvatarV1MustBeStoppedBeforeEndOfInvitationPeriod(msg.sender, 1); - } + function registerHuman(address _inviter, bytes32 _metadataDigest) external { + if (_inviter == address(0)) { + // to self-register yourself if you are a stopped v1 user, + // leave the inviter address as zero. + + // only available for v1 users with stopped v1 mint, for initial bootstrap period + (address v1CirclesStatus, uint256 v1LastTouched) = _registerHuman(msg.sender); + // check if v1 Circles exists and has been stopped + if (v1CirclesStatus != CIRCLES_STOPPED_V1) { + revert CirclesHubRegisterAvatarV1MustBeStoppedBeforeEndOfInvitationPeriod(msg.sender, 0); + } + // if it has been stopped, did it stop before the end of the invitation period? + if (v1LastTouched >= invitationOnlyTime) { + revert CirclesHubRegisterAvatarV1MustBeStoppedBeforeEndOfInvitationPeriod(msg.sender, 1); + } + } else { + // if someone has invited you by trusting your address ahead of this call, + // they must themselves be a registered human, and they must pay the invitation cost (after invitation period). - // store the metadata digest for the avatar metadata - if (_metadataDigest != bytes32(0)) { - nameRegistry.setMetadataDigest(msg.sender, _metadataDigest); - } - } + if (!isHuman(_inviter)) { + revert CirclesHubMustBeHuman(msg.sender, 0); + } - /** - * @notice Invite human allows to register another human avatar. - * The inviter must burn twice the welcome bonus of their own Circles, - * and the invited human receives the welcome bonus in their personal Circles. - * The inviter is set to trust the invited avatar. - * @param _human avatar of the human to invite - */ - function inviteHuman(address _human) external { - if (!isHuman(msg.sender)) { - revert CirclesHubMustBeHuman(msg.sender, 0); - } + if (!isTrusted(_inviter, msg.sender)) { + revert CirclesHubInvalidTrustReceiver(msg.sender, 0); + } - // register the invited human; reverts if they already exist - // it checks the status of the avatar in v1, but regardless of the status - // we can proceed to register the avatar in v2 (they might not be able to mint yet - // if they have not stopped their v1 contract) - _registerHuman(_human); + // register the invited human; reverts if they already exist + // it checks the status of the avatar in v1, but regardless of the status + // we can proceed to register the avatar in v2 (they might not be able to mint yet + // if they have not stopped their v1 contract) + _registerHuman(msg.sender); - if (block.timestamp > invitationOnlyTime) { - // after the bootstrap period, the inviter must burn the invitation cost - _burnAndUpdateTotalSupply(msg.sender, toTokenId(msg.sender), INVITATION_COST); + if (block.timestamp > invitationOnlyTime) { + // after the invitation period, the inviter must burn the invitation cost + _burnAndUpdateTotalSupply(_inviter, toTokenId(_inviter), INVITATION_COST); - // todo: re-discuss desired approach to welcome bonus vs migration - // invited receives the welcome bonus in their personal Circles - _mintAndUpdateTotalSupply(_human, toTokenId(_human), WELCOME_BONUS, ""); + // mint the welcome bonus to the newly registered human + _mintAndUpdateTotalSupply(msg.sender, toTokenId(msg.sender), WELCOME_BONUS, ""); + } } - // set trust to indefinite future, but avatar can edit this later - _trust(msg.sender, _human, INDEFINITE_FUTURE); + // store the metadata digest for the avatar metadata + if (_metadataDigest != bytes32(0)) { + nameRegistry.setMetadataDigest(msg.sender, _metadataDigest); + } } /** @@ -333,7 +339,8 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { /** * @notice Trust allows to trust another address for a certain period of time. * Expiry times in the past are set to the current block timestamp. - * @param _trustReceiver address that is trusted by the caller + * @param _trustReceiver address that is trusted by the caller. The trust receiver + * does not (yet) need to be registered as an avatar. * @param _expiry expiry time in seconds since unix epoch until when trust is valid * @dev Trust is directional and can be set by the caller to any address. * The trusted address does not (yet) have to be registered in the Hub contract. @@ -345,11 +352,11 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { if (_trustReceiver == address(0) || _trustReceiver == SENTINEL) { // You cannot trust the zero address or the sentinel address. // Reserved addresses for logic. - revert CirclesHubInvalidTrustReceiver(_trustReceiver, 0); + revert CirclesHubInvalidTrustReceiver(_trustReceiver, 1); } if (_trustReceiver == msg.sender) { // You cannot edit your own trust relation. - revert CirclesHubInvalidTrustReceiver(_trustReceiver, 1); + revert CirclesHubInvalidTrustReceiver(_trustReceiver, 2); } // expiring trust cannot be set in the past if (_expiry < block.timestamp) _expiry = uint96(block.timestamp); diff --git a/src/operators/SignedPathOperator.sol b/src/operators/SignedPathOperator.sol index 3c412a3..f7948e8 100644 --- a/src/operators/SignedPathOperator.sol +++ b/src/operators/SignedPathOperator.sol @@ -42,11 +42,4 @@ contract SignedPathOperator is BaseOperator, TypeDefinitions { // Call the hub to operate the flow matrix hub.operateFlowMatrix(_flowVertices, _flow, _streams, _packedCoordinates); } - - // Internal functions - - // function _extractSource(bytes calldata _packedCoordinates, uint256 _sourceIndex) internal pure returns (uint16) { - // return - // uint16(uint8(_packedCoordinates[_sourceIndex])) << 8 | uint16(uint8(_packedCoordinates[_sourceIndex + 1])); - // } } diff --git a/test/hub/V1MintStatusUpdate.t.sol b/test/hub/V1MintStatusUpdate.t.sol index 62b26e1..75345a5 100644 --- a/test/hub/V1MintStatusUpdate.t.sol +++ b/test/hub/V1MintStatusUpdate.t.sol @@ -64,13 +64,19 @@ contract V1MintStatusUpdateTest is Test, TimeCirclesSetup, HumanRegistration { vm.startPrank(addresses[0]); tokenAlice.stop(); assertTrue(tokenAlice.stopped(), "Token not stopped"); - mockHub.registerHuman(bytes32(0)); + mockHub.registerHuman(address(0), bytes32(0)); vm.stopPrank(); assertTrue(mockHub.isHuman(addresses[0]), "Alice not registered"); // Alice invites Bob, while he is still active in V1 + // to do that she must trust Bob, and then he can register with Alice as inviter vm.prank(addresses[0]); - mockHub.inviteHuman(addresses[1]); + // Alice trusts Bob + mockHub.trust(addresses[1], type(uint96).max); + // Bob registers with Alice as inviter + vm.prank(addresses[1]); + // Bob calls register Human with Alice as inviter + mockHub.registerHuman(addresses[0], bytes32(0)); assertTrue(mockHub.isHuman(addresses[1]), "Bob not registered"); // move time From 8d1a185a14e1b4ac6d8d06721325f27a30946cd7 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Wed, 28 Aug 2024 23:50:36 +0100 Subject: [PATCH 18/20] (hub): correct explicit groupMint: people who have opted in to consented flow should also be able to explicitly mint into groups that have not opted into consented flow --- src/hub/Hub.sol | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol index 7612c48..3f77bc3 100644 --- a/src/hub/Hub.sol +++ b/src/hub/Hub.sol @@ -426,7 +426,7 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { for (uint256 i = 0; i < _collateralAvatars.length; i++) { collateral[i] = toTokenId(_collateralAvatars[i]); } - _groupMint(msg.sender, msg.sender, _group, collateral, _amounts, _data); + _groupMint(msg.sender, msg.sender, _group, collateral, _amounts, _data, true); } /** @@ -663,6 +663,8 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { * @param _collateral array of (personal or group) avatar addresses to be used as collateral * @param _amounts array of amounts of collateral to be used for minting * @param _data (optional) additional data to be passed to the mint policy, treasury and minter + * @param _explicitCall true if the call is made explicitly over groupMint(), or false if + * it is called as part of a path transfer */ function _groupMint( address _sender, @@ -670,7 +672,8 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { address _group, uint256[] memory _collateral, uint256[] memory _amounts, - bytes memory _data + bytes memory _data, + bool _explicitCall ) internal { if (_collateral.length != _amounts.length) { // Collateral and amount arrays must have equal length. @@ -694,7 +697,8 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { // check the group trusts the collateral // and if the sender has opted into consented flow, the sender must also trust the the group - bool isValidCollateral = isPermittedFlow(_sender, _group, collateralAvatar); + bool isValidCollateral = + _explicitCall ? isTrusted(_group, collateralAvatar) : isPermittedFlow(_sender, _group, collateralAvatar); if (!isValidCollateral) { // Group does not trust collateral, or flow edge is not permitted @@ -877,7 +881,8 @@ contract Hub is Circles, TypeDefinitions, IHubErrors { to, // group; for triggering group mint, to == the group to mint for ids, // collateral amounts, // amounts - "" // path-based group mints never send data to the mint policy + "", // path-based group mints never send data to the mint policy + false ); } From 6641047a5751e46cf2129b6fbabc625ddc1eba72 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Thu, 29 Aug 2024 20:09:24 +0100 Subject: [PATCH 19/20] (InflationaryCircles): prefix s- to symbols of inflationary CRC ERC20 --- src/lift/InflationaryCircles.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lift/InflationaryCircles.sol b/src/lift/InflationaryCircles.sol index e7674c1..720a8b7 100644 --- a/src/lift/InflationaryCircles.sol +++ b/src/lift/InflationaryCircles.sol @@ -11,6 +11,8 @@ import "./ERC20InflationaryBalances.sol"; contract InflationaryCircles is MasterCopyNonUpgradable, ERC20InflationaryBalances, ERC1155Holder { // Constants + string internal constant INFLATIONARY_SYMBOL_PREFIX = "s-"; + // State variables IHubV2 public hub; @@ -89,7 +91,7 @@ contract InflationaryCircles is MasterCopyNonUpgradable, ERC20InflationaryBalanc } function symbol() external view returns (string memory) { - return nameRegistry.symbol(avatar); + return string(abi.encodePacked(INFLATIONARY_SYMBOL_PREFIX, nameRegistry.symbol(avatar))); } function decimals() external pure returns (uint8) { From 62cd5fc4c7b3335e1a33c5b035b367fdca2c78d6 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Thu, 29 Aug 2024 20:44:54 +0100 Subject: [PATCH 20/20] (deploy): deploy artefacts on Gnosis Chain and Chiado as rc-v0.3.6-alpha --- ...ts-rc-0.3.6-alpha-6641047-240829-201137.txt | 9 +++++++++ ...do-rc-0.3.6-alpha-6641047-240829-201137.log | 18 ++++++++++++++++++ .../constructorArgs_BaseGroupMintPolicy.txt | 1 + .../constructorArgs_ERC20Lift.txt | 1 + .../constructorArgs_Hub.txt | 1 + ...onstructorArgs_MastercopyDemurrageERC20.txt | 1 + ...tructorArgs_MastercopyInflationaryERC20.txt | 1 + ...constructorArgs_MastercopyStandardVault.txt | 1 + .../constructorArgs_Migration.txt | 1 + .../constructorArgs_NameRegistry.txt | 1 + .../constructorArgs_StandardTreasury.txt | 1 + .../constructorArgs_BaseGroupMintPolicy.txt | 1 + .../constructorArgs_ERC20Lift.txt | 1 + .../constructorArgs_Hub.txt | 1 + ...onstructorArgs_MastercopyDemurrageERC20.txt | 1 + ...tructorArgs_MastercopyInflationaryERC20.txt | 1 + ...constructorArgs_MastercopyStandardVault.txt | 1 + .../constructorArgs_Migration.txt | 1 + .../constructorArgs_NameRegistry.txt | 1 + .../constructorArgs_StandardTreasury.txt | 1 + ...ts-rc-0.3.6-alpha-6641047-240829-202221.txt | 9 +++++++++ ...in-rc-0.3.6-alpha-6641047-240829-202221.log | 18 ++++++++++++++++++ 22 files changed, 72 insertions(+) create mode 100644 script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/chiado-artefacts-rc-0.3.6-alpha-6641047-240829-201137.txt create mode 100644 script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/chiado-rc-0.3.6-alpha-6641047-240829-201137.log create mode 100644 script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_BaseGroupMintPolicy.txt create mode 100644 script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_ERC20Lift.txt create mode 100644 script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_Hub.txt create mode 100644 script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyDemurrageERC20.txt create mode 100644 script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyInflationaryERC20.txt create mode 100644 script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyStandardVault.txt create mode 100644 script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_Migration.txt create mode 100644 script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_NameRegistry.txt create mode 100644 script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_StandardTreasury.txt create mode 100644 script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_BaseGroupMintPolicy.txt create mode 100644 script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_ERC20Lift.txt create mode 100644 script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_Hub.txt create mode 100644 script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyDemurrageERC20.txt create mode 100644 script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyInflationaryERC20.txt create mode 100644 script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyStandardVault.txt create mode 100644 script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_Migration.txt create mode 100644 script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_NameRegistry.txt create mode 100644 script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_StandardTreasury.txt create mode 100644 script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/gnosischain-artefacts-rc-0.3.6-alpha-6641047-240829-202221.txt create mode 100644 script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/gnosischain-rc-0.3.6-alpha-6641047-240829-202221.log diff --git a/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/chiado-artefacts-rc-0.3.6-alpha-6641047-240829-201137.txt b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/chiado-artefacts-rc-0.3.6-alpha-6641047-240829-201137.txt new file mode 100644 index 0000000..56fe91b --- /dev/null +++ b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/chiado-artefacts-rc-0.3.6-alpha-6641047-240829-201137.txt @@ -0,0 +1,9 @@ +{"contractName":"Hub","deployedAddress":"0xb80feeDfEce647dDc709777D5094fACD157BA001","sourcePath":"src/hub/Hub.sol:Hub","constructor-args":"0xdbF22D4e8962Db3b2F1d9Ff55be728A887e47710 0x24b3fDCdD9fef844fB3094ef43c0A6Ac23a6dF9E 0x12E815963A0b910288C7256CAD0d345c8F5db08E 0xBD2D6Fbb6A702B04B750Bc9942fBaAE81187355E 0xC06ADED7950429FdF2023e139B076f6BaFf9Fe1C 1675209600 31540000 https://gateway.aboutcircles.com/v1/circles/{id}.json","argumentsFile":"constructorArgs_Hub.txt"} +{"contractName":"Migration","deployedAddress":"0x12E815963A0b910288C7256CAD0d345c8F5db08E","sourcePath":"src/migration/Migration.sol:Migration","constructor-args":"0xdbF22D4e8962Db3b2F1d9Ff55be728A887e47710 0xb80feeDfEce647dDc709777D5094fACD157BA001 1675209600","argumentsFile":"constructorArgs_Migration.txt"} +{"contractName":"NameRegistry","deployedAddress":"0x24b3fDCdD9fef844fB3094ef43c0A6Ac23a6dF9E","sourcePath":"src/names/NameRegistry.sol:NameRegistry","constructor-args":"0xb80feeDfEce647dDc709777D5094fACD157BA001","argumentsFile":"constructorArgs_NameRegistry.txt"} +{"contractName":"ERC20Lift","deployedAddress":"0xBD2D6Fbb6A702B04B750Bc9942fBaAE81187355E","sourcePath":"src/lift/ERC20Lift.sol:ERC20Lift","constructor-args":"0xb80feeDfEce647dDc709777D5094fACD157BA001 0x24b3fDCdD9fef844fB3094ef43c0A6Ac23a6dF9E 0xe7ef9F22107C5A55033c4C73595e64c9b3155b46 0x4b5bF5436dA471BECF73a7832481431AE257c6bF","argumentsFile":"constructorArgs_ERC20Lift.txt"} +{"contractName":"StandardTreasury","deployedAddress":"0xC06ADED7950429FdF2023e139B076f6BaFf9Fe1C","sourcePath":"src/treasury/StandardTreasury.sol:StandardTreasury","constructor-args":"0xb80feeDfEce647dDc709777D5094fACD157BA001 0x1be5E03E44CeD1018977510d6Ad55f8D1259a039","argumentsFile":"constructorArgs_StandardTreasury.txt"} +{"contractName":"BaseGroupMintPolicy","deployedAddress":"0xE35c66531aF28660a1CdfA3dd0b1C1C0245D2F67","sourcePath":"src/groups/BaseMintPolicy.sol:MintPolicy","constructor-args":"","argumentsFile":"constructorArgs_BaseGroupMintPolicy.txt"} +{"contractName":"MastercopyDemurrageERC20","deployedAddress":"0xe7ef9F22107C5A55033c4C73595e64c9b3155b46","sourcePath":"src/lift/DemurrageCircles.sol:DemurrageCircles","constructor-args":"","argumentsFile":"constructorArgs_MastercopyDemurrageERC20.txt"} +{"contractName":"MastercopyInflationaryERC20","deployedAddress":"0x4b5bF5436dA471BECF73a7832481431AE257c6bF","sourcePath":"src/lift/InflationaryCircles.sol:InflationaryCircles","constructor-args":"","argumentsFile":"constructorArgs_MastercopyInflationaryERC20.txt"} +{"contractName":"MastercopyStandardVault","deployedAddress":"0x1be5E03E44CeD1018977510d6Ad55f8D1259a039","sourcePath":"src/treasury/StandardVault.sol:StandardVault","constructor-args":"","argumentsFile":"constructorArgs_MastercopyStandardVault.txt"} diff --git a/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/chiado-rc-0.3.6-alpha-6641047-240829-201137.log b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/chiado-rc-0.3.6-alpha-6641047-240829-201137.log new file mode 100644 index 0000000..a0eb743 --- /dev/null +++ b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/chiado-rc-0.3.6-alpha-6641047-240829-201137.log @@ -0,0 +1,18 @@ +Chiado deployment +================= +Deployment Date: 2024-08-29 20:11:37 +Version: rc-0.3.6-alpha +Git Commit: 6641047a5751e46cf2129b6fbabc625ddc1eba72 +Deployer Address: 0x7619F26728Ced663E50E578EB6ff42430931564c, Intitial nonce: 176 +Compiler Version: v0.8.23+commit.f704f362 + +Deployed Contracts: +Hub: 0xb80feeDfEce647dDc709777D5094fACD157BA001 +Migration: 0x12E815963A0b910288C7256CAD0d345c8F5db08E +NameRegistry: 0x24b3fDCdD9fef844fB3094ef43c0A6Ac23a6dF9E +ERC20Lift: 0xBD2D6Fbb6A702B04B750Bc9942fBaAE81187355E +StandardTreasury: 0xC06ADED7950429FdF2023e139B076f6BaFf9Fe1C +BaseGroupMintPolicy: 0xE35c66531aF28660a1CdfA3dd0b1C1C0245D2F67 +MastercopyDemurrageERC20: 0xe7ef9F22107C5A55033c4C73595e64c9b3155b46 +MastercopyInflationaryERC20: 0x4b5bF5436dA471BECF73a7832481431AE257c6bF +MastercopyStandardVault: 0x1be5E03E44CeD1018977510d6Ad55f8D1259a039 diff --git a/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_BaseGroupMintPolicy.txt b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_BaseGroupMintPolicy.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_BaseGroupMintPolicy.txt @@ -0,0 +1 @@ + diff --git a/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_ERC20Lift.txt b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_ERC20Lift.txt new file mode 100644 index 0000000..c2a79df --- /dev/null +++ b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_ERC20Lift.txt @@ -0,0 +1 @@ +0xb80feeDfEce647dDc709777D5094fACD157BA001 0x24b3fDCdD9fef844fB3094ef43c0A6Ac23a6dF9E 0xe7ef9F22107C5A55033c4C73595e64c9b3155b46 0x4b5bF5436dA471BECF73a7832481431AE257c6bF diff --git a/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_Hub.txt b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_Hub.txt new file mode 100644 index 0000000..f27b767 --- /dev/null +++ b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_Hub.txt @@ -0,0 +1 @@ +0xdbF22D4e8962Db3b2F1d9Ff55be728A887e47710 0x24b3fDCdD9fef844fB3094ef43c0A6Ac23a6dF9E 0x12E815963A0b910288C7256CAD0d345c8F5db08E 0xBD2D6Fbb6A702B04B750Bc9942fBaAE81187355E 0xC06ADED7950429FdF2023e139B076f6BaFf9Fe1C 1675209600 31540000 https://gateway.aboutcircles.com/v1/circles/{id}.json diff --git a/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyDemurrageERC20.txt b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyDemurrageERC20.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyDemurrageERC20.txt @@ -0,0 +1 @@ + diff --git a/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyInflationaryERC20.txt b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyInflationaryERC20.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyInflationaryERC20.txt @@ -0,0 +1 @@ + diff --git a/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyStandardVault.txt b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyStandardVault.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_MastercopyStandardVault.txt @@ -0,0 +1 @@ + diff --git a/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_Migration.txt b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_Migration.txt new file mode 100644 index 0000000..01efc9d --- /dev/null +++ b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_Migration.txt @@ -0,0 +1 @@ +0xdbF22D4e8962Db3b2F1d9Ff55be728A887e47710 0xb80feeDfEce647dDc709777D5094fACD157BA001 1675209600 diff --git a/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_NameRegistry.txt b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_NameRegistry.txt new file mode 100644 index 0000000..4224459 --- /dev/null +++ b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_NameRegistry.txt @@ -0,0 +1 @@ +0xb80feeDfEce647dDc709777D5094fACD157BA001 diff --git a/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_StandardTreasury.txt b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_StandardTreasury.txt new file mode 100644 index 0000000..e377bbb --- /dev/null +++ b/script/deployments/chiado-rc-0.3.6-alpha-6641047-240829-201137/constructorArgs_StandardTreasury.txt @@ -0,0 +1 @@ +0xb80feeDfEce647dDc709777D5094fACD157BA001 0x1be5E03E44CeD1018977510d6Ad55f8D1259a039 diff --git a/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_BaseGroupMintPolicy.txt b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_BaseGroupMintPolicy.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_BaseGroupMintPolicy.txt @@ -0,0 +1 @@ + diff --git a/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_ERC20Lift.txt b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_ERC20Lift.txt new file mode 100644 index 0000000..5a6dc85 --- /dev/null +++ b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_ERC20Lift.txt @@ -0,0 +1 @@ +0xa5c7ADAE2fd3844f12D52266Cb7926f8649869Da 0x738fFee24770d0DE1f912adf2B48b0194780E9AD 0x26fA0d8A877E6A6170E4613fA7Cb0359efdb985d 0x38A8d2A38A788A388D20210ff18847EF7e13eda5 diff --git a/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_Hub.txt b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_Hub.txt new file mode 100644 index 0000000..569abad --- /dev/null +++ b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_Hub.txt @@ -0,0 +1 @@ +0x29b9a7fBb8995b2423a71cC17cf9810798F6C543 0x738fFee24770d0DE1f912adf2B48b0194780E9AD 0xe1dCE89512bE1AeDf94faAb7115A1Ba6AEff4201 0xB6B79BeEfd58cf33b298A456934554cf440354aD 0xbb76CF35ec106c5c7a447246257dcfCB7244cA04 1602720000 31540000 https://gateway.aboutcircles.com/v1/circles/{id}.json diff --git a/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyDemurrageERC20.txt b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyDemurrageERC20.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyDemurrageERC20.txt @@ -0,0 +1 @@ + diff --git a/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyInflationaryERC20.txt b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyInflationaryERC20.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyInflationaryERC20.txt @@ -0,0 +1 @@ + diff --git a/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyStandardVault.txt b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyStandardVault.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_MastercopyStandardVault.txt @@ -0,0 +1 @@ + diff --git a/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_Migration.txt b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_Migration.txt new file mode 100644 index 0000000..f363876 --- /dev/null +++ b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_Migration.txt @@ -0,0 +1 @@ +0x29b9a7fBb8995b2423a71cC17cf9810798F6C543 0xa5c7ADAE2fd3844f12D52266Cb7926f8649869Da 1602720000 diff --git a/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_NameRegistry.txt b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_NameRegistry.txt new file mode 100644 index 0000000..761a5f5 --- /dev/null +++ b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_NameRegistry.txt @@ -0,0 +1 @@ +0xa5c7ADAE2fd3844f12D52266Cb7926f8649869Da diff --git a/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_StandardTreasury.txt b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_StandardTreasury.txt new file mode 100644 index 0000000..e9f085d --- /dev/null +++ b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/constructorArgs_StandardTreasury.txt @@ -0,0 +1 @@ +0xa5c7ADAE2fd3844f12D52266Cb7926f8649869Da 0x570E9D5472994543C5032c83538B41983cF4F90E diff --git a/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/gnosischain-artefacts-rc-0.3.6-alpha-6641047-240829-202221.txt b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/gnosischain-artefacts-rc-0.3.6-alpha-6641047-240829-202221.txt new file mode 100644 index 0000000..15b672e --- /dev/null +++ b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/gnosischain-artefacts-rc-0.3.6-alpha-6641047-240829-202221.txt @@ -0,0 +1,9 @@ +{"contractName":"Hub","deployedAddress":"0xa5c7ADAE2fd3844f12D52266Cb7926f8649869Da","sourcePath":"src/hub/Hub.sol:Hub","constructor-args":"0x29b9a7fBb8995b2423a71cC17cf9810798F6C543 0x738fFee24770d0DE1f912adf2B48b0194780E9AD 0xe1dCE89512bE1AeDf94faAb7115A1Ba6AEff4201 0xB6B79BeEfd58cf33b298A456934554cf440354aD 0xbb76CF35ec106c5c7a447246257dcfCB7244cA04 1602720000 31540000 https://gateway.aboutcircles.com/v1/circles/{id}.json","argumentsFile":"constructorArgs_Hub.txt"} +{"contractName":"Migration","deployedAddress":"0xe1dCE89512bE1AeDf94faAb7115A1Ba6AEff4201","sourcePath":"src/migration/Migration.sol:Migration","constructor-args":"0x29b9a7fBb8995b2423a71cC17cf9810798F6C543 0xa5c7ADAE2fd3844f12D52266Cb7926f8649869Da 1602720000","argumentsFile":"constructorArgs_Migration.txt"} +{"contractName":"NameRegistry","deployedAddress":"0x738fFee24770d0DE1f912adf2B48b0194780E9AD","sourcePath":"src/names/NameRegistry.sol:NameRegistry","constructor-args":"0xa5c7ADAE2fd3844f12D52266Cb7926f8649869Da","argumentsFile":"constructorArgs_NameRegistry.txt"} +{"contractName":"ERC20Lift","deployedAddress":"0xB6B79BeEfd58cf33b298A456934554cf440354aD","sourcePath":"src/lift/ERC20Lift.sol:ERC20Lift","constructor-args":"0xa5c7ADAE2fd3844f12D52266Cb7926f8649869Da 0x738fFee24770d0DE1f912adf2B48b0194780E9AD 0x26fA0d8A877E6A6170E4613fA7Cb0359efdb985d 0x38A8d2A38A788A388D20210ff18847EF7e13eda5","argumentsFile":"constructorArgs_ERC20Lift.txt"} +{"contractName":"StandardTreasury","deployedAddress":"0xbb76CF35ec106c5c7a447246257dcfCB7244cA04","sourcePath":"src/treasury/StandardTreasury.sol:StandardTreasury","constructor-args":"0xa5c7ADAE2fd3844f12D52266Cb7926f8649869Da 0x570E9D5472994543C5032c83538B41983cF4F90E","argumentsFile":"constructorArgs_StandardTreasury.txt"} +{"contractName":"BaseGroupMintPolicy","deployedAddress":"0x5Ea08c967C69255d82a4d26e36823a720E7D0317","sourcePath":"src/groups/BaseMintPolicy.sol:MintPolicy","constructor-args":"","argumentsFile":"constructorArgs_BaseGroupMintPolicy.txt"} +{"contractName":"MastercopyDemurrageERC20","deployedAddress":"0x26fA0d8A877E6A6170E4613fA7Cb0359efdb985d","sourcePath":"src/lift/DemurrageCircles.sol:DemurrageCircles","constructor-args":"","argumentsFile":"constructorArgs_MastercopyDemurrageERC20.txt"} +{"contractName":"MastercopyInflationaryERC20","deployedAddress":"0x38A8d2A38A788A388D20210ff18847EF7e13eda5","sourcePath":"src/lift/InflationaryCircles.sol:InflationaryCircles","constructor-args":"","argumentsFile":"constructorArgs_MastercopyInflationaryERC20.txt"} +{"contractName":"MastercopyStandardVault","deployedAddress":"0x570E9D5472994543C5032c83538B41983cF4F90E","sourcePath":"src/treasury/StandardVault.sol:StandardVault","constructor-args":"","argumentsFile":"constructorArgs_MastercopyStandardVault.txt"} diff --git a/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/gnosischain-rc-0.3.6-alpha-6641047-240829-202221.log b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/gnosischain-rc-0.3.6-alpha-6641047-240829-202221.log new file mode 100644 index 0000000..aee76c8 --- /dev/null +++ b/script/deployments/gnosischain-rc-0.3.6-alpha-6641047-240829-202221/gnosischain-rc-0.3.6-alpha-6641047-240829-202221.log @@ -0,0 +1,18 @@ +Gnosis Chain deployment +================= +Deployment Date: 2024-08-29 20:22:21 +Version: rc-0.3.6-alpha +Git Commit: 6641047a5751e46cf2129b6fbabc625ddc1eba72 +Deployer Address: 0x7619F26728Ced663E50E578EB6ff42430931564c, Initial nonce: 74 +Compiler Version: v0.8.23+commit.f704f362 + +Deployed Contracts: +Hub: 0xa5c7ADAE2fd3844f12D52266Cb7926f8649869Da +Migration: 0xe1dCE89512bE1AeDf94faAb7115A1Ba6AEff4201 +NameRegistry: 0x738fFee24770d0DE1f912adf2B48b0194780E9AD +ERC20Lift: 0xB6B79BeEfd58cf33b298A456934554cf440354aD +StandardTreasury: 0xbb76CF35ec106c5c7a447246257dcfCB7244cA04 +BaseGroupMintPolicy: 0x5Ea08c967C69255d82a4d26e36823a720E7D0317 +MastercopyDemurrageERC20: 0x26fA0d8A877E6A6170E4613fA7Cb0359efdb985d +MastercopyInflationaryERC20: 0x38A8d2A38A788A388D20210ff18847EF7e13eda5 +MastercopyStandardVault: 0x570E9D5472994543C5032c83538B41983cF4F90E