Skip to content

Instantly share code, notes, and snippets.

@maheshmurthy
Last active April 13, 2023 19:34
Show Gist options
  • Save maheshmurthy/cc352f8546f48855ca9efa907145c6e7 to your computer and use it in GitHub Desktop.
Save maheshmurthy/cc352f8546f48855ca9efa907145c6e7 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract DelegateRegistry {
struct Delegate {
address delegateAddress;
address tokenAddress;
uint256 tokenChainId;
}
mapping(address => mapping(address => mapping(uint256 => Delegate))) public delegates;
address public owner;
event DelegateAdded(address indexed delegateAddress, address tokenAddress, uint256 tokenChainId);
event DelegateRemoved(address indexed delegateAddress);
event DelegateMetadataUpdated(address indexed delegateAddress, address tokenAddress, uint256 chainId, bytes metadata);
constructor() {
owner = msg.sender;
}
function addDelegate(address _tokenAddress, uint256 _tokenChainId, bytes memory _metadata) public {
Delegate memory newDelegate = Delegate({
delegateAddress: msg.sender,
tokenAddress: _tokenAddress,
tokenChainId: _tokenChainId,
});
require(delegates[msg.sender][_tokenAddress][_tokenChainId].delegateAddress == address(0), "Delegate already exists for this address, token address, and chain ID");
delegates[msg.sender][_tokenAddress][_tokenChainId] = newDelegate;
emit DelegateAdded(msg.sender, _tokenAddress, _tokenChainId, _metadata);
}
function removeDelegate() public {
address delegateAddress = msg.sender;
Delegate memory removedDelegate = delegates[delegateAddress][delegateAddress][0];
delete delegates[delegateAddress][removedDelegate.tokenAddress][removedDelegate.tokenChainId];
emit DelegateRemoved(removedDelegate.delegateAddress);
}
function updateDelegateMetadata(address _tokenAddress, uint256 _chainId, bytes memory _metadata) public {
Delegate storage delegateToUpdate = delegates[msg.sender][_tokenAddress][_chainId];
require(delegateToUpdate.delegateAddress == msg.sender, "Delegate does not exist for this address, token address, and chain ID");
delegateToUpdate.metadata = _metadata;
emit DelegateMetadataUpdated(msg.sender, _tokenAddress, _chainId, _metadata);
}
function getDelegate(address _delegateAddress, address _tokenAddress, uint256 _tokenChainId) public view returns (Delegate memory) {
return delegates[_delegateAddress][_tokenAddress][_tokenChainId];
}
}
@rsolari
Copy link

rsolari commented Apr 10, 2023

Nice! Looks good.

Implementation questions and nits:

line 8:

         uint256 chainId;

Maybe we call this tokenChainId so it's obviously not the delegate's chainId.

line 9:

        bytes metadata; // with predefined schema

It's quite expensive to store this blob. Maybe we should just emit this data in the event logs?

Open questions:

  • Is it worth enforcing a schema for the metadata at the smart-contract level? I know we went back-and-forth a bit on this in chat, so maybe we should bring it up on the next call
  • Should we support updating a delegate's metadata? I'd say yes.

@maheshmurthy
Copy link
Author

Agree with all the suggestions.

  1. Updated to tokenChainId.
  2. Just emitting metadata as event log.
  3. Added function to update metadata

I don't think it's worth enforcing schema at the contract level, it will cost extra gas for not much in return. But agree, we can discuss with everyone on the call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment