(Re)Introducing ERC721x: A safer implementation of the ERC721 standard
Jun 23, 2023
This has been made public, you can find it here.
CyberKongz lead Solidity Dev, OwlofMoistness, has developed the ERC721x standard in a continued effort to develop WEB3 technology and push the space forwards. In short the standard adds multiple layers of security to your NFTs, allowing you to sleep comfortably at night.
On-chain 2FA
It is no secret there are some bad players in the space. Scams run rife throughout WEB3 and with one simple click you can be drained of everything in your wallet. We aim to change that with the technology to protect our holders. This standard essentially gives your NFTs 2-Factor-Authentication (2FA), assigning a second wallet as a ‘Guardian’ preventing your precious NFTs from being transferred without your authorization.
We are excited to announce that the next CyberKongz mint will make use of the ERC721x, continuing our tradition of having the safest community in Web3.
Explanation
There are 2 layers to ERC721x, ‘locking’ and ‘guarding’.
Locking
When you ‘lock’ your NFT, you are making use of the lock registry, a system that plugs itself on the ERC721 standard that needs very little gas and allows whitelisted addresses to lock and unlock assets in place. The assets cannot be moved until it is unassigned from the lock registry.
Stake your assets without losing ownership. The lock registry was built with the ability to have parallel staking in mind. Assets could be used in multiple systems where locking the asset in place would be beneficial.
Guarding
The Guardian Contract performs similarly to locking with some adjustments… Instead of the wallet holding the NFT (Wallet A) locking the NFT, the holding wallet assigns a second wallet (Wallet B) as a ‘Guardian’. The Guardian wallet can then lock the assets in the holding wallet a second time. However this time, it is the Guardian wallet that needs to approve the asset for transfer, ostensibly creating on-chain 2FA. It is advised that the Guardian wallet is a hard or cold wallet to ensure the highest level of security.
Read more about the Guardian Contract on Owl’s GitHub here.
Read more about Locking and Guarding on Owl's Medium here.
What does this solve
We all know that hot wallets are convenient and we love using them for our daily activities, but with that convenience comes great vulnerability… The Guardian Contract allows you to enjoy the convenience of a hot wallet, while adding the security of a cold/hardware/multi-sig wallet on top. It even allows you to guard assets that already reside on a hardware wallet with a second hardware wallet to add another layer of protection from signing unwanted transfer or approval transactions.
Furthermore, scams will be harder to pull off.
Email scams, social engineering scams, luring users to approve OpenSea sales, approvals to some rogue contract, hot wallet hacks or giving seed phrases away etc…
All those methods won’t work if your assets are locked up.
The amount of hacks would reduce drastically, resulting in saving hundreds of thousands if not millions in NFT value for users.
How it works
Let's take a look at the technical details.
ERC721x Contract
This standard allows contracts that implement the ILock interface to lock/unlock assets in place to enable/disable them from being transferred.
How does this work?
The Lock Registry contains four mappings:
mapping(address => bool) public approvedContract;
mapping(uint256 => uint256) public lockCount;
mapping(uint256 => mapping(uint256 => address)) public lockMap;
mapping(uint256 => mapping(address => uint256)) public lockMapIndex;
The first, approvedContract, is a mapping that checks if an address is allowed to lock/unlock assets from the collection. This mapping is updated by the owner of the contract (EOA or multisig for example).
lockCount is a mapping that tracks how many locks a token possesses. As long as the lock count is > 0, the token cannot move. Once there are no more locks, the token is free to move once again.
lockMap and lockMapIndex work together.
lockMap is a double mapping that connects a token ID to the address that locked it.
lockMap[tokenId][lockIndex] => contract that locked
lockMapIndex is a double mapping that connects a token ID to the lockIndex of the adddress that locked it.
lockMapIndex[tokenId][lockingContract] => lock Index of locking contract
Those 2 mappings are necessary to easily track and delete lock when a contract unlocks a token.
Interface
The IERC721x interface is very simple:
interface IERC721x {
/**
* @dev Returns if the token is locked (non-transferrable) or not.
*/
function isUnlocked(uint256 _id) external view returns(bool);
/**
* @dev Returns the amount of locks on the token.
*/
function lockCount(uint256 _tokenId) external view returns(uint256);
/**
* @dev Returns if a contract is allowed to lock/unlock tokens.
*/
function approvedContract(address _contract) external view returns(bool);
/**
* @dev Returns the contract that locked a token at a specific index in the mapping.
*/
function lockMap(uint256 _tokenId, uint256 _index) external view returns(address);
/**
* @dev Returns the mapping index of a contract that locked a token.
*/
function lockMapIndex(uint256 _tokenId, address _contract) external
view returns(uint256);
/**
* @dev Locks a token, preventing it from being transferrable
*/
function lockId(uint256 _id) external;
/**
* @dev Unlocks a token.
*/
function unlockId(uint256 _id) external;
/**
* @dev Unlocks a token from a given contract if the contract is no longer approved.
*/
function freeId(uint256 _id, address _contract) external;
}
An approved contract can lock or unlock an asset. Locking an asset twice will revert, same behavior for double unlocking.
freeId is an emergency function that can only be called under a specific condition. It behaves similarly to the unlockId function. It can only be called if the previously approved contract that locked the asset is no longer approved. This means that you will be required to change approvedContract[badContract] => false by calling updateApprovedContracts and unset the initially approved contract. This should only happen if the locking contract has bad logic and prevents people from unlocking assets. By disapproving the defective contract, we allow users to remove the lock to enable transferring their asset if they choose to.
Closing thoughts
The CyberKongz Genkai mint will make use of this new standard, continuing our tradition of having the safest community in Web3. We believe this technology is a step in the right direction for security within web3. We encourage other projects in the space to adopt the ERC721x standard, we have already seen some notable collections like 9gag & Keungz implement the standard in their collections. For more information on the standard and implementing it in your own project, please read up on Owl’s Medium and Github.
KONGZ TOGETHER STRONG!
Join our Discord to always stay up to date and become part of our community: https://discord.com/invite/cyberkongz