Erc-20

可升級代幣可以出現在資產列表中嗎?

  • June 18, 2022

我們正在使用標準代理模式和 OpenZeppelin 模板啟動 ERC20Upgradeable 令牌。

此外,我們將 Gnosis 安全用於多重簽名功能。

Gnosis 保險箱的使用者體驗煩惱是代幣餘額不會出現在保險箱的資產列表中。這意味著使用者必須點擊“新交易”>“合約互動”並從鏈中讀取他們的餘額。

我認為代幣餘額不會出現在資產列表中,因為:

  • 代理合約不是 ERC-20(畢竟是代理,不是代幣合約),並且
  • 邏輯合約不儲存狀態(因此,它沒有捕捉到保險箱持有非零數量代幣的事實)。

有什麼方法可以讓 Gnosis UI 跟踪可升級的代幣餘額並將其直接呈現給使用者?

編輯:以下是兩個契約。它們是相同的,只是一個可升級而另一個不可升級。在 Gnosis 安全中,只有不可升級的才會顯示為資產。

可升級合約:

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";

contract PureToken is Initializable, ERC20Upgradeable, AccessControlUpgradeable {

   bytes32 public constant USER_ROLE = keccak256("USER_ROLE");

   function initialize() public initializer {
       _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
       __ERC20_init("PureToken","PPT");
       _mint(address(0xeF008d5228cEFD52d806876586aFf7d0371Eb91B), 17 * 10 ** decimals());
   }
   
   function mint(address to, uint256 amount) public {
       require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Must be ADMIN.");
       require(hasRole(USER_ROLE, to), "Recipient must be USER.");
       _mint(to, amount);
   }

   function burn(address from, uint256 amount) public {
       require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Must be ADMIN.");
       _burn(from, amount);
   }

   function transfer(address to, uint256 value) public override returns (bool) {
       require(hasRole(USER_ROLE, to), "Recipient must be USER.");
       return super.transfer(to, value);
   }

   function transferFrom(address from, address to, uint256 value) public override returns (bool) {
       require(hasRole(USER_ROLE, to), "Recipient must be USER.");
       require(hasRole(USER_ROLE, msg.sender), "You must hold USER status to send tokens.");
       return super.transferFrom(from, to, value);
   }
}

不可升級的令牌

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

contract PureToken is Initializable, ERC20, AccessControl {

   bytes32 public constant USER_ROLE = keccak256("USER_ROLE");
   
   constructor() ERC20("PureToken", "PPT") {
       _mint(address(0xeF008d5228cEFD52d806876586aFf7d0371Eb91B), 19 * 10 ** decimals());
       _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
   }

    function mint(address to, uint256 amount) public {
       require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Can not mint: you are not an ADMIN.");
       require(hasRole(USER_ROLE, to), "Can not mint: recipient is not a USER.");
       _mint(to, amount);
   }

   function burn(address from, uint256 amount) public {
       require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Can not burn: you are not an ADMIN.");
       _burn(from, amount);
   }

   function transfer(address to, uint256 value) public override returns (bool) {
       require(hasRole(USER_ROLE, to), "Can not transfer: recipient is not a USER.");
       return super.transfer(to, value);
   }

   function transferFrom(address from, address to, uint256 value) public override returns (bool) {
       require(hasRole(USER_ROLE, to), "Can not transfer: recipient is not a USER.");
       require(hasRole(USER_ROLE, msg.sender), "You must hold USER status to send tokens.");
       return super.transferFrom(from, to, value);
   }
}

Gnosis Safe 適用於任何 ERC-20 代幣,包括代理代幣。

必須有一些其他問題在您的問題中並不明顯,因為它缺乏

  • 使用 Gnosis Safe 測試令牌的方法
  • 您的令牌原始碼

我懷疑你是對的,原因是你的代理合約不是 ERC20 合約。由於您使用的是 OpenZeppelin 可升級性,因此您的代理合約不會公開 ERC20 合約的方法,例如decimals, balanceOf, transfer,而是公開諸如implementation,upgradeTo等方法。因此 gnosis 沒有簡單的方法來檢測它是 ERC20。

引用自:https://ethereum.stackexchange.com/questions/130358