From 44dc93c8e11104d312270fb6db48a25eea5104ac Mon Sep 17 00:00:00 2001 From: "calvo.generico" Date: Fri, 29 Nov 2024 14:14:16 -0300 Subject: [PATCH 1/7] simplest Erc20 and Erc721. --- permission-templates/erc20.yaml | 53 ++++++++++++++++ permission-templates/erc721.yaml | 101 +++++++++++++++++++++++++++++++ src/SomeErc20.sol | 33 ++++++++++ src/SomeErc721.sol | 63 +++++++++++++++++++ 4 files changed, 250 insertions(+) create mode 100644 permission-templates/erc20.yaml create mode 100644 permission-templates/erc721.yaml create mode 100644 src/SomeErc20.sol create mode 100644 src/SomeErc721.sol diff --git a/permission-templates/erc20.yaml b/permission-templates/erc20.yaml new file mode 100644 index 0000000..5036a41 --- /dev/null +++ b/permission-templates/erc20.yaml @@ -0,0 +1,53 @@ +contracts: + - address: + methods: + # ERC164 + - signature: totalSupply() + read: + type: public + write: + type: public + - signature: balanceOf(account) + read: + type: checkArgument + argIndex: 0 + write: + type: closed + - signature: allowance(owner, spender) + read: + type: oneOf + rules: + - type: checkArgument + argIndex: 0 + - type: checkArgument + argIndex: 1 + write: + type: closed + - signature: approve(spender, amount) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: transferFrom(sender, recipient, amount) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: increaseAllowance(spender, addedValue) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: decreaseAllowance(spender, subtractedValue) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public \ No newline at end of file diff --git a/permission-templates/erc721.yaml b/permission-templates/erc721.yaml new file mode 100644 index 0000000..948eb9f --- /dev/null +++ b/permission-templates/erc721.yaml @@ -0,0 +1,101 @@ +contracts: + - address: + methods: + # ERC164 + - signature: "function number(byte4) (bool)" + read: + type: public + write: + type: public + # ERC721 + - signature: balanceOf(address) (uint256) + read: + type: checkArgument + argIndex: 0 + write: + type: forbidden + - signature: "ownerOf(uint256) (address)" + read: + type: public + write: + type: forbidden + postRead: + type: "responseIsCurrentUser" + - signature: "safeTransferFrom(address, address, uint256)" + read: + type: oneOf + rules: + - type: checkArgument + argIndex: 0 + - type: checkArgument + argIndex: 1 + write: + type: oneOf + rules: + - type: checkArgument + argIndex: 0 + - type: checkArgument + argIndex: 1 + - signature: approve(address, uint256) + read: + type: public + write: + type: public + - signature: getApproved() + read: + type: public + write: + type: public + - signature: setApprovalForAll + read: + type: public + write: + type: public + - signature: isApprovedForAll(address, address) + read: + type: public + write: + type: public + - signature: safeTransferFrom(address, address, uint256) + # This work because we check that msg.sender is the current user and the method reverts + # if msg.sender has no permission over the token to move. + read: + type: public + write: + type: public + # ERC721Metadata + - signature: name() + read: + type: public + write: + type: public + - signature: symbol() + read: + type: public + write: + type: public + - signature: tokenUri(uint256) + read: + type: public + write: + type: public + # ERC721MetadataEnumerable + - signature: totalSupply() + read: + type: public + write: + type: public + - signature: tokenOfOwnerByIndex(address, uint256) + read: + type: checkArgument + argIndex: 0 + write: + type: checkArgument + argIndex: 0 + - signature: tokenByIndex(index) + read: + type: checkArgument + argIndex: 0 + write: + type: checkArgument + argIndex: 0 \ No newline at end of file diff --git a/src/SomeErc20.sol b/src/SomeErc20.sol new file mode 100644 index 0000000..d303a6b --- /dev/null +++ b/src/SomeErc20.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract SomeErc20 is ERC20 { + uint8 private _decimals; + mapping(address => uint256) private puclicThresholds; + + + constructor() ERC20("SomeErc20", "SE20") { + _decimals = 4; + } + + function mint(address _to, uint256 _amount) public returns (bool) { + _mint(_to, _amount); + return true; + } + + function decimals() public view override returns (uint8) { + return _decimals; + } + + function puclicThreshold(address target) public view returns (uint256, bool) { + uint256 threshold = puclicThresholds[target]; + return (threshold, balanceOf(target) >= threshold); + } + + function changePublicThreshold(uint256 publicThreshold) external { + puclicThresholds[msg.sender] = publicThreshold; + } +} diff --git a/src/SomeErc721.sol b/src/SomeErc721.sol new file mode 100644 index 0000000..9500313 --- /dev/null +++ b/src/SomeErc721.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import {ERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; + +contract SomeErc721 is ERC721 { + uint256 private _lastId; + mapping(address owner => uint256[]) private publicInventories; + + constructor() ERC721("SomeToken", "ST") { + _lastId = 0; + } + + function mintNext(address target) + public + returns (uint256) + { + _lastId += 1; + + uint256 newItemId = _lastId; + _mint(target, newItemId); + + return newItemId; + } + + function publicInventory(address owner) public view returns (uint256[] memory) { + return publicInventories[owner]; + } + + function expose(uint256 tokenId) public { + if (ownerOf(tokenId) != msg.sender) { + revert(); + } + + uint256[] storage inventory = publicInventories[msg.sender]; + + for (uint i = 0; i < inventory.length; i++) { + if (inventory[i] == tokenId) { + return; + } + } + + publicInventories[msg.sender].push(tokenId); + } + + + function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) { + if (auth != address(0)) { + uint256[] storage inventory = publicInventories[auth]; + for (uint i = 0; i < inventory.length; i++) { + if (inventory[i] == tokenId) { + inventory[i] = inventory[inventory.length - 1]; + inventory.pop(); + break; + } + } + } + + return super._update(to, tokenId, auth); + } +} \ No newline at end of file From 3bb6fe16f62c0adb2c3ad1da4481f69fb0c84e64 Mon Sep 17 00:00:00 2001 From: "calvo.generico" Date: Wed, 4 Dec 2024 08:35:28 -0300 Subject: [PATCH 2/7] added new contracts. --- bash_scripts/deploy_tokens.sh | 43 ++++++++++++ foundry.toml | 1 + .../erc20-public-scoped-balance.yaml | 68 +++++++++++++++++++ .../erc20-share-balance-with-users.yaml | 68 +++++++++++++++++++ .../erc20-share-scoped-balance.yaml | 68 +++++++++++++++++++ ...c721.yaml => erc721-public-selection.yaml} | 2 +- ...Erc20.sol => PublicScopedBalanceErc20.sol} | 12 ++-- ...meErc721.sol => PublicSelectionErc721.sol} | 4 +- src/ShareBalanceErc20.sol | 41 +++++++++++ src/ShareScopedBalanceErc20.sol | 61 +++++++++++++++++ 10 files changed, 359 insertions(+), 9 deletions(-) create mode 100755 bash_scripts/deploy_tokens.sh create mode 100644 permission-templates/erc20-public-scoped-balance.yaml create mode 100644 permission-templates/erc20-share-balance-with-users.yaml create mode 100644 permission-templates/erc20-share-scoped-balance.yaml rename permission-templates/{erc721.yaml => erc721-public-selection.yaml} (98%) rename src/{SomeErc20.sol => PublicScopedBalanceErc20.sol} (63%) rename src/{SomeErc721.sol => PublicSelectionErc721.sol} (93%) create mode 100644 src/ShareBalanceErc20.sol create mode 100644 src/ShareScopedBalanceErc20.sol diff --git a/bash_scripts/deploy_tokens.sh b/bash_scripts/deploy_tokens.sh new file mode 100755 index 0000000..e8c769e --- /dev/null +++ b/bash_scripts/deploy_tokens.sh @@ -0,0 +1,43 @@ +#!/bin/env sh + +set -e +set -o xtrace + +forge create --zksync \ + --rpc-url http://localhost:3050 \ + --private-key 0x87ce66d9f787696d21af61750c1c3310099f27fb7e7259a193a8c514293a7c0c \ + --verify \ + --verifier zksync \ + --verifier-url http://localhost:3070/contract_verification \ + src/PublicScopedBalanceErc20.sol:PublicScopedBalanceErc20 \ + --constructor-args "PublicScopedBalanceErc20-posta" "PEB20P"; + +forge create --zksync \ + --rpc-url http://localhost:3050 \ + --private-key 0x87ce66d9f787696d21af61750c1c3310099f27fb7e7259a193a8c514293a7c0c \ + --verify \ + --verifier zksync \ + --verifier-url http://localhost:3070/contract_verification \ + src/ShareBalanceErc20.sol:ShareBalanceErc20 \ + --constructor-args "ShareBalanceErc20-posta" "SB20P"; + +forge create --zksync \ + --rpc-url http://localhost:3050 \ + --private-key 0x87ce66d9f787696d21af61750c1c3310099f27fb7e7259a193a8c514293a7c0c \ + --verify \ + --verifier zksync \ + --verifier-url http://localhost:3070/contract_verification \ + src/ShareScopedBalanceErc20.sol:ShareScopedBalanceErc20 \ + --constructor-args "ShareScopedBalanceErc20-posta" "SSBE20P"; + + +forge create --zksync \ + --rpc-url http://localhost:3050 \ + --private-key 0x87ce66d9f787696d21af61750c1c3310099f27fb7e7259a193a8c514293a7c0c \ + --verify \ + --verifier zksync \ + --verifier-url http://localhost:3070/contract_verification \ + src/PublicSelectionErc721.sol:PublicSelectionErc721 \ + --constructor-args "PublicSelectionErc721-posta" "PC721P"; + + diff --git a/foundry.toml b/foundry.toml index 6529fb8..1d30ab7 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,6 +2,7 @@ src = "src" out = "out" libs = ["lib"] +solc="0.8.24" [profile.default.zksync] zksolc = "1.5.6" diff --git a/permission-templates/erc20-public-scoped-balance.yaml b/permission-templates/erc20-public-scoped-balance.yaml new file mode 100644 index 0000000..fa6baff --- /dev/null +++ b/permission-templates/erc20-public-scoped-balance.yaml @@ -0,0 +1,68 @@ +contracts: + - address: + methods: + - signature: totalSupply() + read: + type: public + write: + type: public + - signature: balanceOf(account) + read: + type: checkArgument + argIndex: 0 + write: + type: closed + - signature: allowance(owner, spender) + read: + type: oneOf + rules: + - type: checkArgument + argIndex: 0 + - type: checkArgument + argIndex: 1 + write: + type: closed + - signature: approve(spender, amount) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: transferFrom(sender, recipient, amount) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: increaseAllowance(spender, addedValue) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: decreaseAllowance(spender, subtractedValue) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: authorizedBalanceOf(address)(uint256) + read: + type: public + write: + type: public + - signature: puclicThreshold(address)(uint256, bool) + read: + type: public + write: + type: closed + - signature: changePublicThreshold(uint256) + read: + type: public + write: + type: public + diff --git a/permission-templates/erc20-share-balance-with-users.yaml b/permission-templates/erc20-share-balance-with-users.yaml new file mode 100644 index 0000000..cb91236 --- /dev/null +++ b/permission-templates/erc20-share-balance-with-users.yaml @@ -0,0 +1,68 @@ +contracts: + - address: + methods: + - signature: totalSupply() + read: + type: public + write: + type: public + - signature: balanceOf(account) + read: + type: checkArgument + argIndex: 0 + write: + type: closed + - signature: allowance(owner, spender) + read: + type: oneOf + rules: + - type: checkArgument + argIndex: 0 + - type: checkArgument + argIndex: 1 + write: + type: closed + - signature: approve(spender, amount) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: transferFrom(sender, recipient, amount) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: increaseAllowance(spender, addedValue) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: decreaseAllowance(spender, subtractedValue) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: authorizedBalanceOf(address)(uint256) + read: + type: public + write: + type: closed + - signature: shareBalanceWith(address)(uint256) + read: + type: public + write: + type: public + - signature: hideBalanceFrom(address) + read: + type: public + write: + type: public + diff --git a/permission-templates/erc20-share-scoped-balance.yaml b/permission-templates/erc20-share-scoped-balance.yaml new file mode 100644 index 0000000..a800ad8 --- /dev/null +++ b/permission-templates/erc20-share-scoped-balance.yaml @@ -0,0 +1,68 @@ +contracts: + - address: + methods: + # ERC164 + - signature: totalSupply() + read: + type: public + write: + type: public + - signature: balanceOf(account) + read: + type: checkArgument + argIndex: 0 + write: + type: closed + - signature: allowance(owner, spender) + read: + type: oneOf + rules: + - type: checkArgument + argIndex: 0 + - type: checkArgument + argIndex: 1 + write: + type: closed + - signature: approve(spender, amount) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: transferFrom(sender, recipient, amount) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: increaseAllowance(spender, addedValue) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: decreaseAllowance(spender, subtractedValue) + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: authorizedBalanceOf(address)(uint256) + read: + type: public + write: + type: closed + - signature: shareBalanceWith(address, uint256)(uint256) + read: + type: public + write: + type: public + - signature: hideBalanceFrom(address) + read: + type: public + write: + type: public diff --git a/permission-templates/erc721.yaml b/permission-templates/erc721-public-selection.yaml similarity index 98% rename from permission-templates/erc721.yaml rename to permission-templates/erc721-public-selection.yaml index 948eb9f..a049050 100644 --- a/permission-templates/erc721.yaml +++ b/permission-templates/erc721-public-selection.yaml @@ -2,7 +2,7 @@ contracts: - address: methods: # ERC164 - - signature: "function number(byte4) (bool)" + - signature: "supportsInterface(bytes4)" read: type: public write: diff --git a/src/SomeErc20.sol b/src/PublicScopedBalanceErc20.sol similarity index 63% rename from src/SomeErc20.sol rename to src/PublicScopedBalanceErc20.sol index d303a6b..50f734e 100644 --- a/src/SomeErc20.sol +++ b/src/PublicScopedBalanceErc20.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.24; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -contract SomeErc20 is ERC20 { +contract PublicScopedBalanceErc20 is ERC20 { uint8 private _decimals; mapping(address => uint256) private puclicThresholds; @@ -13,8 +13,8 @@ contract SomeErc20 is ERC20 { _decimals = 4; } - function mint(address _to, uint256 _amount) public returns (bool) { - _mint(_to, _amount); + function mint(address to, uint256 amount) public returns (bool) { + _mint(to, amount); return true; } @@ -22,12 +22,12 @@ contract SomeErc20 is ERC20 { return _decimals; } - function puclicThreshold(address target) public view returns (uint256, bool) { + function publicThreshold(address target) public view returns (uint256, bool) { uint256 threshold = puclicThresholds[target]; return (threshold, balanceOf(target) >= threshold); } - function changePublicThreshold(uint256 publicThreshold) external { - puclicThresholds[msg.sender] = publicThreshold; + function changePublicThreshold(uint256 newThreshold) external { + puclicThresholds[msg.sender] = newThreshold; } } diff --git a/src/SomeErc721.sol b/src/PublicSelectionErc721.sol similarity index 93% rename from src/SomeErc721.sol rename to src/PublicSelectionErc721.sol index 9500313..bb032b4 100644 --- a/src/SomeErc721.sol +++ b/src/PublicSelectionErc721.sol @@ -5,11 +5,11 @@ pragma solidity 0.8.24; import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import {ERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; -contract SomeErc721 is ERC721 { +contract PublicSelectionErc721 is ERC721 { uint256 private _lastId; mapping(address owner => uint256[]) private publicInventories; - constructor() ERC721("SomeToken", "ST") { + constructor(string memory name, string memory symbol) ERC721(name, symbol) { _lastId = 0; } diff --git a/src/ShareBalanceErc20.sol b/src/ShareBalanceErc20.sol new file mode 100644 index 0000000..d9b2826 --- /dev/null +++ b/src/ShareBalanceErc20.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract ShareBalanceErc20 is ERC20 { + uint8 private _decimals; + mapping(address => uint256) private puclicThresholds; + mapping(address => mapping(address => bool)) private permissions; + + + constructor(string memory name, string memory symbol) ERC20(name, symbol) { + _decimals = 4; + } + + function decimals() public view override returns (uint8) { + return _decimals; + } + + function mint(address _to, uint256 _amount) public returns (bool) { + _mint(_to, _amount); + return true; + } + + function authorizedBalanceOf(address account) public view returns (uint256) { + if (account != msg.sender && !permissions[account][msg.sender]) { + revert(); + } + return super.balanceOf(account); + } + + + function shareBalanceWith(address reader) public { + permissions[msg.sender][reader] = true; + } + + function hideBalanceFrom(address reader) public { + permissions[msg.sender][reader] = false; + } +} diff --git a/src/ShareScopedBalanceErc20.sol b/src/ShareScopedBalanceErc20.sol new file mode 100644 index 0000000..70b7258 --- /dev/null +++ b/src/ShareScopedBalanceErc20.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract ShareScopedBalanceErc20 is ERC20 { + uint8 private _decimals; + mapping(address => uint256) private puclicThresholds; + mapping(address => mapping(address => uint256)) private permissions; + + + constructor(string memory name, string memory symbol) ERC20(name, symbol) { + _decimals = 4; + } + + function decimals() public view override returns (uint8) { + return _decimals; + } + + function mint(address _to, uint256 _amount) public returns (bool) { + _mint(_to, _amount); + return true; + } + + function authorizedBalanceOf(address account) public view returns (uint256) { + if (msg.sender == account) { + return super.balanceOf(account); + } else { + return min(super.balanceOf(account), permissions[account][msg.sender]); + } + } + + function min(uint256 n1, uint256 n2) internal pure returns (uint256) { + if (n1 <= n2) { + return n1; + } else { + return n2; + } + } + + + function shareBalanceWith(address reader, uint256 amount) public { + permissions[msg.sender][reader] = amount; + } + + function hideBalanceFrom(address reader) public { + permissions[msg.sender][reader] = 0; + } +} + + + +// forge create --zksync \ +// --rpc-url http://localhost:3050 \ +// --private-key 0x87ce66d9f787696d21af61750c1c3310099f27fb7e7259a193a8c514293a7c0c \ +// --verify \ +// --verifier-url http://localhost:3020/api \ +// --verifier zksync \ +// src/ShareScopedBalanceErc20.sol:ShareScopedBalanceErc20 \ +// --constructor-args "ShareScopedBalanceErc20" "SSBE20" \ No newline at end of file From 17effeb571c50e1f17bb5373ae7071bead2e2baa Mon Sep 17 00:00:00 2001 From: "calvo.generico" Date: Wed, 4 Dec 2024 16:04:35 -0300 Subject: [PATCH 3/7] improved permission template for erc20 public scoped. --- .../erc20-public-scoped-balance.yaml | 66 +++++++++++++++---- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/permission-templates/erc20-public-scoped-balance.yaml b/permission-templates/erc20-public-scoped-balance.yaml index fa6baff..08de0b0 100644 --- a/permission-templates/erc20-public-scoped-balance.yaml +++ b/permission-templates/erc20-public-scoped-balance.yaml @@ -1,18 +1,19 @@ contracts: - address: methods: - - signature: totalSupply() + # ERC20 standard + - signature: function totalSupply() public view returns (uint256) read: type: public write: type: public - - signature: balanceOf(account) + - signature: function balanceOf(address account) public view returns (uint256) read: type: checkArgument argIndex: 0 write: - type: closed - - signature: allowance(owner, spender) + type: closed + - signature: function allowance(address owner, address spender) public view returns (uint256) read: type: oneOf rules: @@ -21,48 +22,85 @@ contracts: - type: checkArgument argIndex: 1 write: - type: closed - - signature: approve(spender, amount) + type: closed + - signature: function approve(address spender, uint256 value) public returns (bool) # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: transferFrom(sender, recipient, amount) + - signature: function transfer(address to, uint256 value) public returns (bool) # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: increaseAllowance(spender, addedValue) + - signature: function transferFrom(address from, address to, uint256 value) public returns (bool) # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: decreaseAllowance(spender, subtractedValue) + + # + # Open Zeppelion extended methods + # + - signature: function increaseAllowance(address spender, address addedValue) public # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: authorizedBalanceOf(address)(uint256) + - signature: function decreaseAllowance(address spender, address subtractedValue) public + # This doesn't leek information because we validate that current user + # is msg.sender. read: type: public write: - type: public - - signature: puclicThreshold(address)(uint256, bool) + type: public + - signature: function symbol() public view returns (string memory) read: type: public write: - type: closed - - signature: changePublicThreshold(uint256) + type: public + - signature: function decimals() public view returns (uint8) read: type: public write: type: public + # + # IRC165 + # + - signature: function supportsInterface(bytes4 interfaceID) external view returns (bool) + read: + type: public + write: + type: public + + # + # Extended methods + # + - signature: function mint(address to, uint256 amount) public returns (bool) + read: + type: group + groups: + - admins + write: + type: group + groups: + - admins + - signature: function publicThreshold(address target) public view returns (uint256, bool) + read: + type: public + write: + type: closed + - signature: function changePublicThreshold(uint256 newThreshold) external + read: + type: public + write: + type: public From 7e43fa8c41f9c36c2a929dbc259efe3ac98cbb32 Mon Sep 17 00:00:00 2001 From: "calvo.generico" Date: Wed, 4 Dec 2024 16:08:58 -0300 Subject: [PATCH 4/7] erc20 share blanace with users template improved. --- .../erc20-share-balance-with-users.yaml | 69 +++++++++++++++---- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/permission-templates/erc20-share-balance-with-users.yaml b/permission-templates/erc20-share-balance-with-users.yaml index cb91236..73288ad 100644 --- a/permission-templates/erc20-share-balance-with-users.yaml +++ b/permission-templates/erc20-share-balance-with-users.yaml @@ -1,18 +1,19 @@ contracts: - address: methods: - - signature: totalSupply() + # ERC20 standard + - signature: function totalSupply() public view returns (uint256) read: type: public write: type: public - - signature: balanceOf(account) + - signature: function balanceOf(address account) public view returns (uint256) read: type: checkArgument argIndex: 0 write: - type: closed - - signature: allowance(owner, spender) + type: closed + - signature: function allowance(address owner, address spender) public view returns (uint256) read: type: oneOf rules: @@ -21,48 +22,90 @@ contracts: - type: checkArgument argIndex: 1 write: - type: closed - - signature: approve(spender, amount) + type: closed + - signature: function approve(address spender, uint256 value) public returns (bool) # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: transferFrom(sender, recipient, amount) + - signature: function transfer(address to, uint256 value) public returns (bool) # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: increaseAllowance(spender, addedValue) + - signature: function transferFrom(address from, address to, uint256 value) public returns (bool) # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: decreaseAllowance(spender, subtractedValue) + + # + # Open Zeppelion extended methods + # + - signature: function increaseAllowance(address spender, address addedValue) public # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: authorizedBalanceOf(address)(uint256) + - signature: function decreaseAllowance(address spender, address subtractedValue) public + # This doesn't leek information because we validate that current user + # is msg.sender. read: type: public write: - type: closed - - signature: shareBalanceWith(address)(uint256) + type: public + - signature: function symbol() public view returns (string memory) read: type: public write: type: public - - signature: hideBalanceFrom(address) + - signature: function decimals() public view returns (uint8) read: type: public write: type: public + # + # IRC165 + # + - signature: function supportsInterface(bytes4 interfaceID) external view returns (bool) + read: + type: public + write: + type: public + + # + # Extended methods + # + - signature: function mint(address to, uint256 amount) public returns (bool) + read: + type: group + groups: + - admins + write: + type: group + groups: + - admins + - signature: function authorizedBalanceOf(address account) public view returns (uint256) + read: + type: public + write: + type: public + - signature: function shareBalanceWith(address reader) public + read: + type: closed + write: + type: public + - signature: function hideBalanceFrom(address reader) public + read: + type: closed + write: + type: public From ade67a3b328634206efe83699a5c551fec14e20b Mon Sep 17 00:00:00 2001 From: "calvo.generico" Date: Wed, 4 Dec 2024 16:13:07 -0300 Subject: [PATCH 5/7] improved missing erc20 template. --- .../erc20-share-balance-with-users.yaml | 4 +- .../erc20-share-scoped-balance.yaml | 71 +++++++++++++++---- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/permission-templates/erc20-share-balance-with-users.yaml b/permission-templates/erc20-share-balance-with-users.yaml index 73288ad..ba1cb81 100644 --- a/permission-templates/erc20-share-balance-with-users.yaml +++ b/permission-templates/erc20-share-balance-with-users.yaml @@ -101,11 +101,11 @@ contracts: type: public - signature: function shareBalanceWith(address reader) public read: - type: closed + type: public write: type: public - signature: function hideBalanceFrom(address reader) public read: - type: closed + type: public write: type: public diff --git a/permission-templates/erc20-share-scoped-balance.yaml b/permission-templates/erc20-share-scoped-balance.yaml index a800ad8..73fe2b9 100644 --- a/permission-templates/erc20-share-scoped-balance.yaml +++ b/permission-templates/erc20-share-scoped-balance.yaml @@ -1,19 +1,19 @@ contracts: - address: methods: - # ERC164 - - signature: totalSupply() + # ERC20 standard + - signature: function totalSupply() public view returns (uint256) read: type: public write: type: public - - signature: balanceOf(account) + - signature: function balanceOf(address account) public view returns (uint256) read: type: checkArgument argIndex: 0 write: - type: closed - - signature: allowance(owner, spender) + type: closed + - signature: function allowance(address owner, address spender) public view returns (uint256) read: type: oneOf rules: @@ -22,46 +22,89 @@ contracts: - type: checkArgument argIndex: 1 write: - type: closed - - signature: approve(spender, amount) + type: closed + - signature: function approve(address spender, uint256 value) public returns (bool) # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: transferFrom(sender, recipient, amount) + - signature: function transfer(address to, uint256 value) public returns (bool) # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: increaseAllowance(spender, addedValue) + - signature: function transferFrom(address from, address to, uint256 value) public returns (bool) # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: decreaseAllowance(spender, subtractedValue) + + # + # Open Zeppelion extended methods + # + - signature: function increaseAllowance(address spender, address addedValue) public # This doesn't leek information because we validate that current user # is msg.sender. read: type: public write: type: public - - signature: authorizedBalanceOf(address)(uint256) + - signature: function decreaseAllowance(address spender, address subtractedValue) public + # This doesn't leek information because we validate that current user + # is msg.sender. + read: + type: public + write: + type: public + - signature: function symbol() public view returns (string memory) read: type: public write: - type: closed - - signature: shareBalanceWith(address, uint256)(uint256) + type: public + - signature: function decimals() public view returns (uint8) + read: + type: public + write: + type: public + + # + # IRC165 + # + - signature: function supportsInterface(bytes4 interfaceID) external view returns (bool) + read: + type: public + write: + type: public + + # + # Extended methods + # + - signature: function mint(address to, uint256 amount) public returns (bool) + read: + type: group + groups: + - admins + write: + type: group + groups: + - admins + - signature: function authorizedBalanceOf(address account) public view returns (uint256) + read: + type: public + write: + type: public + - signature: function shareBalanceWith(address reader, uint256 amount) public read: type: public write: type: public - - signature: hideBalanceFrom(address) + - signature: function hideBalanceFrom(address reader) public read: type: public write: From 405b26a8276753293d69da9b8e84bff4f2e0c025 Mon Sep 17 00:00:00 2001 From: "calvo.generico" Date: Fri, 6 Dec 2024 16:25:05 -0300 Subject: [PATCH 6/7] corrections --- .../erc721-public-selection.yaml | 69 +++++++++++++------ src/PublicSelectionErc721.sol | 29 ++++---- 2 files changed, 66 insertions(+), 32 deletions(-) diff --git a/permission-templates/erc721-public-selection.yaml b/permission-templates/erc721-public-selection.yaml index a049050..18887c8 100644 --- a/permission-templates/erc721-public-selection.yaml +++ b/permission-templates/erc721-public-selection.yaml @@ -2,26 +2,27 @@ contracts: - address: methods: # ERC164 - - signature: "supportsInterface(bytes4)" + - signature: function supportsInterface(bytes4 interfaceId) public view override(ERC165, IERC165) returns (bool) read: type: public write: - type: public - # ERC721 - - signature: balanceOf(address) (uint256) + type: closed + # IERC721 + - signature: function balanceOf(address owner) public view returns (uint256) read: type: checkArgument argIndex: 0 write: - type: forbidden - - signature: "ownerOf(uint256) (address)" + type: closed + - signature: function ownerOf(uint256 tokenId) public view returns (address) read: type: public write: - type: forbidden + type: closed postRead: type: "responseIsCurrentUser" - - signature: "safeTransferFrom(address, address, uint256)" + index: 0 + - signature: function safeTransferFrom(address from, address to, uint256 tokenId) public read: type: oneOf rules: @@ -36,45 +37,45 @@ contracts: argIndex: 0 - type: checkArgument argIndex: 1 - - signature: approve(address, uint256) + - signature: function approve(address to, uint256 tokenId) public read: type: public write: type: public - - signature: getApproved() + - signature: function getApproved(uint256 tokenId) public view returns (address) read: type: public write: type: public - - signature: setApprovalForAll + - signature: function setApprovalForAll(address operator, bool approved) public read: type: public write: type: public - - signature: isApprovedForAll(address, address) + - signature: function isApprovedForAll(address owner, address operator) public view returns (bool) read: type: public write: type: public - - signature: safeTransferFrom(address, address, uint256) + - signature: function safeTransferFrom(address from, address to, uint256 tokenId) public # This work because we check that msg.sender is the current user and the method reverts # if msg.sender has no permission over the token to move. read: - type: public + type: public write: type: public # ERC721Metadata - - signature: name() + - signature: function name() public view returns (string) read: type: public write: type: public - - signature: symbol() + - signature: function symbol() public view rtual returns (string) read: type: public write: type: public - - signature: tokenUri(uint256) + - signature: function tokenURI(uint256 tokenId) public view returns (string memory) read: type: public write: @@ -85,17 +86,45 @@ contracts: type: public write: type: public - - signature: tokenOfOwnerByIndex(address, uint256) + - signature: function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) read: type: checkArgument argIndex: 0 write: type: checkArgument argIndex: 0 - - signature: tokenByIndex(index) + - signature: function tokenByIndex(uint256 index) public view returns (uint256) read: type: checkArgument argIndex: 0 write: type: checkArgument - argIndex: 0 \ No newline at end of file + argIndex: 0 + + # Extender methods + - signature: function mintNext(address target) public returns (uint256) + read: + type: group + groups: + - admins + write: + type: group + groups: + - admins + + - signature: function publicInventory(address owner) public view returns (uint256[]) + read: + type: public + write: + type: public + + - signature: function expose(uint256 tokenId) public + read: + type: public + write: + type: public + - signature: function hide(uint256 tokenId) public + read: + type: public + write: + type: public diff --git a/src/PublicSelectionErc721.sol b/src/PublicSelectionErc721.sol index bb032b4..2ee7b83 100644 --- a/src/PublicSelectionErc721.sol +++ b/src/PublicSelectionErc721.sol @@ -13,10 +13,7 @@ contract PublicSelectionErc721 is ERC721 { _lastId = 0; } - function mintNext(address target) - public - returns (uint256) - { + function mintNext(address target) public returns (uint256) { _lastId += 1; uint256 newItemId = _lastId; @@ -45,19 +42,27 @@ contract PublicSelectionErc721 is ERC721 { publicInventories[msg.sender].push(tokenId); } + function hide(uint256 tokenId) public { + return _hideFor(tokenId, msg.sender); + } + function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) { if (auth != address(0)) { - uint256[] storage inventory = publicInventories[auth]; - for (uint i = 0; i < inventory.length; i++) { - if (inventory[i] == tokenId) { - inventory[i] = inventory[inventory.length - 1]; - inventory.pop(); - break; - } - } + _hideFor(tokenId, auth); } return super._update(to, tokenId, auth); } + + function _hideFor(uint256 tokenId, address user) internal { + uint256[] storage exposed = publicInventories[user]; + for (uint i = 0; i < exposed.length; i++) { + if (exposed[i] == tokenId) { + exposed[i] = exposed[exposed.length - 1]; + exposed.pop(); + break; + } + } + } } \ No newline at end of file From 17926975b822ec93b44be1de1ebf137f37264662 Mon Sep 17 00:00:00 2001 From: "calvo.generico" Date: Fri, 6 Dec 2024 16:26:34 -0300 Subject: [PATCH 7/7] removed comment --- src/ShareScopedBalanceErc20.sol | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/ShareScopedBalanceErc20.sol b/src/ShareScopedBalanceErc20.sol index 70b7258..5e81ce0 100644 --- a/src/ShareScopedBalanceErc20.sol +++ b/src/ShareScopedBalanceErc20.sol @@ -48,14 +48,3 @@ contract ShareScopedBalanceErc20 is ERC20 { permissions[msg.sender][reader] = 0; } } - - - -// forge create --zksync \ -// --rpc-url http://localhost:3050 \ -// --private-key 0x87ce66d9f787696d21af61750c1c3310099f27fb7e7259a193a8c514293a7c0c \ -// --verify \ -// --verifier-url http://localhost:3020/api \ -// --verifier zksync \ -// src/ShareScopedBalanceErc20.sol:ShareScopedBalanceErc20 \ -// --constructor-args "ShareScopedBalanceErc20" "SSBE20" \ No newline at end of file