Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cross-chain delegation #169

Merged
merged 4 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 28 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,84 +94,44 @@ The following functions are `onlyOwner`, and since the NFT contract ownership is

### Crosschain

Make sure the main account has sufficient balance on OP Sepolia and Arbitrum Sepolia:
Make sure the main account, Bob and Alice have sufficient balance on OP Sepolia and Arbitrum Sepolia:

```
pnpm bal
```

Deploy:

```
pnpm deploy:all
```

It will:

- Deploy to OP Sepolia
- Deploy to Arbitrum Sepolia

Add a member (mint):
# Deploy to OP Sepolia and Arbitrum Sepolia
pnpm deploy:op-sepolia
pnpm deploy:arbitrum-sepolia

```
./scripts/mint.sh
```

It will:

- Submit a proposal and add a member on OP Sepolia
- Generate a membership proof on OP Sepolia
- Claim that proof on Arbitrum Sepolia
# Add a new member
npx hardhat run scripts/propose.ts --network op-sepolia
npx hardhat run scripts/verify-proof.ts --network op-sepolia
npx hardhat run scripts/claim-membership.ts --network arbitrum-sepolia

Ban a member (burn):
# Ban a member
npx hardhat run scripts/propose-burn.ts --network op-sepolia
npx hardhat run scripts/verify-burn-proof.ts --network op-sepolia
npx hardhat run scripts/claim-burn.ts --network arbitrum-sepolia

```
./scripts/burn.sh
```
# Edit 1 membership NFT metadata
npx hardhat run scripts/propose-metadata.ts --network op-sepolia
npx hardhat run scripts/verify-metadata-proof.ts --network op-sepolia
npx hardhat run scripts/claim-metadata.ts --network arbitrum-sepolia

It will:
# Edit the manifesto
npx hardhat run scripts/propose-manifesto.ts --network op-sepolia
npx hardhat run scripts/verify-manifesto-proof.ts --network op-sepolia
npx hardhat run scripts/claim-manifesto.ts --network arbitrum-sepolia

- Submit a proposal and ban a member on OP Sepolia
- Generate a burn proof on OP Sepolia
- Claim that proof on Arbitrum Sepolia
# Change 1 voting parameter
npx hardhat run scripts/propose-voting-delay.ts --network op-sepolia
npx hardhat run scripts/verify-voting-delay-proof.ts --network op-sepolia
npx hardhat run scripts/claim-voting-delay.ts --network arbitrum-sepolia

Edit membership NFT metadata:

```
./scripts/metadata.sh
# Change delegation
npx hardhat run scripts/propose-delegation.ts --network op-sepolia
npx hardhat run scripts/verify-delegation-proof.ts --network op-sepolia
npx hardhat run scripts/claim-delegation.ts --network arbitrum-sepolia
```

It will:

- Submit a proposal edit the NFT metadata of tokenId 1 on OP Sepolia
- Generate a metadata proof on OP Sepolia
- Claim that proof on Arbitrum Sepolia

Edit the manifesto:

```
./scripts/manifesto.sh
```

It will:

- Submit a proposal to edit the manifesto on OP Sepolia
- Generate a manifesto proof on OP Sepolia
- Claim that proof on Arbitrum Sepolia

Change the voting delay:

```
./scripts/voting-delay.sh
```

It will:

- Submit a proposal to change the voting delay on OP Sepolia
- Generate a voting delay proof on OP Sepolia
- Claim that proof on Arbitrum Sepolia


## Core Dependencies

- Node [v20.9.0](https://nodejs.org/uk/blog/release/v20.9.0/)
Expand Down
66 changes: 63 additions & 3 deletions contracts/variants/crosschain/NFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,15 @@ contract NFT is
/// @notice Tracks token existence on each chain
mapping(uint256 => bool) public existsOnChain;

mapping(address => address) public crosschainDelegates;

/// @notice Operation types for cross-chain message verification
/// @dev Used to differentiate between different types of cross-chain operations
enum OperationType {
MINT, // Mint new token
BURN, // Burn existing token
SET_METADATA // Update token metadata
MINT,
BURN,
SET_METADATA,
SET_DELEGATION
}

/**
Expand Down Expand Up @@ -68,6 +71,13 @@ contract NFT is
*/
event MetadataUpdated(uint256 indexed tokenId, string newUri);

event DelegationUpdated(address indexed delegator, address indexed delegate);
event CrosschainDelegationClaimed(
address indexed delegator,
address indexed delegate,
address indexed claimer
);

/**
* @notice Restricts operations to the home chain
* @dev Used to ensure certain operations only occur on the chain where the contract was originally deployed
Expand Down Expand Up @@ -189,6 +199,32 @@ contract NFT is
return abi.encode(tokenId, uri, digest);
}

function delegate(address delegatee) public virtual override onlyHomeChain {
super.delegate(delegatee);
crosschainDelegates[msg.sender] = delegatee;
emit DelegationUpdated(msg.sender, delegatee);
}

function generateDelegationProof(
address delegator,
address delegatee
) external view returns (bytes memory) {
require(block.chainid == home, "Proofs can only be generated on home chain");
require(crosschainDelegates[delegator] == delegatee, "Invalid delegation state");

bytes32 message = keccak256(
abi.encodePacked(
address(this),
uint8(OperationType.SET_DELEGATION),
delegator,
delegatee
)
);
bytes32 digest = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));

return abi.encode(delegator, delegatee, digest);
}

/**
* @notice Claims a membership on a foreign chain
* @dev Verifies proof and mints token on foreign chain
Expand Down Expand Up @@ -260,6 +296,30 @@ contract NFT is
emit MetadataUpdated(tokenId, uri);
}

function claimDelegation(bytes memory proof) external {
(address delegator, address delegatee, bytes32 digest) = abi.decode(
proof,
(address, address, bytes32)
);

bytes32 message = keccak256(
abi.encodePacked(
address(this),
uint8(OperationType.SET_DELEGATION),
delegator,
delegatee
)
);
bytes32 expectedDigest = keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", message)
);
require(digest == expectedDigest, "Invalid delegation proof");

_delegate(delegator, delegatee);
crosschainDelegates[delegator] = delegatee;
emit CrosschainDelegationClaimed(delegator, delegatee, msg.sender);
}

// Internal Functions

/**
Expand Down
2 changes: 1 addition & 1 deletion deploy/deploy-crosschain-gov.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts } = hre
const { deterministic } = deployments
const { deployer } = await getNamedAccounts()
const salt = hre.ethers.id("Dec-12-v2")
const salt = hre.ethers.id("Dec-17-v1")
const homeChainId = 11155420

function wait(ms: number): Promise<void> {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"scripts": {
"compile": "hardhat compile",
"test": "hardhat test",
"test:all": "./scripts/deploy.sh && ./scripts/mint.sh && ./scripts/burn.sh && ./scripts/metadata.sh && ./scripts/manifesto.sh && ./scripts/voting-delay.sh",
"test:crosschain": "hardhat test test/Gov-crosschain.ts",
"deploy:optimism": "hardhat deploy --network optimism --reset",
"deploy:base": "hardhat deploy --network base --reset",
Expand All @@ -16,6 +15,7 @@
"deploy:base-sepolia": "hardhat deploy --network base-sepolia --reset",
"crosschain:sepolia": "hardhat deploy --network sepolia --tags CrosschainGov --reset",
"crosschain:op-sepolia": "hardhat deploy --network op-sepolia --tags CrosschainGov --reset",
"crosschain:arbitrum-sepolia": "hardhat deploy --network arbitrum-sepolia --tags CrosschainGov --reset",
"deploy:all": "./scripts/deploy.sh",
"bal": "npx hardhat run scripts/check-my-balance.ts",
"verify:setup": "hardhat run scripts/verify-crosschain-setup.ts",
Expand Down
38 changes: 0 additions & 38 deletions scripts/burn.sh

This file was deleted.

Loading
Loading