-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* fix bal script * fix .env * fix script * add auto-delegate * add auto-delegation * add 2 scripts
- Loading branch information
Showing
15 changed files
with
350 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,24 @@ | ||
# Signer Private Key (signer[0]) | ||
SIGNER_PRIVATE_KEY="88888" | ||
|
||
# Optimism Mainnet | ||
OPTIMISM_MAINNET_RPC_ENDPOINT_URL="https://mainnet.optimism.io" | ||
OPTIMISM_MAINNET_PRIVATE_KEY="88888" | ||
OP_ETHERSCAN_API_KEY="88888" | ||
|
||
# Base Mainnet | ||
BASE_MAINNET_RPC_ENDPOINT_URL="https://mainnet.base.org" | ||
BASE_MAINNET_PRIVATE_KEY="88888" | ||
BASE_ETHERSCAN_API_KEY="88888" | ||
|
||
# Sepolia | ||
SEPOLIA_RPC_ENDPOINT_URL="https://ethereum-sepolia.publicnode.com" | ||
SEPOLIA_PRIVATE_KEY="88888" | ||
SEPOLIA_RPC_ENDPOINT_URL="https://sepolia.infura.io/v3/88888" | ||
ETHERSCAN_API_KEY="88888" | ||
|
||
# OP Sepolia | ||
OP_SEPOLIA_RPC_ENDPOINT_URL="https://sepolia.optimism.io" | ||
OP_SEPOLIA_PRIVATE_KEY="88888" | ||
|
||
# Base Sepolia | ||
BASE_SEPOLIA_RPC_ENDPOINT_URL="https://sepolia.base.org" | ||
BASE_SEPOLIA_PRIVATE_KEY="88888" | ||
|
||
# Addresses used when running scripts for testing cross-chain scenarios | ||
ALICE="88888" # Alice // 0xD8a394e7d7894bDF2C57139fF17e5CBAa29Dd977 | ||
JUNGLE="88888" # Jungle Fever // 0xBDC0E420aB9ba144213588A95fa1E5e63CEFf1bE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,7 @@ import "./ProofHandler.sol"; | |
* @title Cross-chain Membership NFT Contract | ||
* @author Web3 Hackers Collective | ||
* @notice Non-transferable NFT implementation for DAO membership with cross-chain capabilities | ||
* @dev Extends OpenZeppelin's NFT standards with cross-chain operation support | ||
* @dev Extends OpenZeppelin's NFT standards with cross-chain operation support and delegation | ||
* @custom:security-contact [email protected] | ||
*/ | ||
contract NFT is | ||
|
@@ -41,7 +41,8 @@ contract NFT is | |
enum OperationType { | ||
MINT, | ||
BURN, | ||
SET_METADATA | ||
SET_METADATA, | ||
DELEGATE | ||
} | ||
|
||
/// @notice Emitted when a membership is claimed | ||
|
@@ -62,6 +63,12 @@ contract NFT is | |
/// @param nonce Operation sequence number | ||
event MetadataUpdated(uint256 indexed tokenId, string newUri, uint256 nonce); | ||
|
||
/// @notice Emitted when delegation is synchronized across chains | ||
/// @param delegator The address delegating their voting power | ||
/// @param delegatee The address receiving the delegation | ||
/// @param nonce Operation sequence number | ||
event DelegationSynced(address indexed delegator, address indexed delegatee, uint256 nonce); | ||
|
||
/// @notice Restricts functions to home chain | ||
modifier onlyHomeChain() { | ||
require(block.chainid == home, "Operation only allowed on home chain"); | ||
|
@@ -88,6 +95,7 @@ contract NFT is | |
home = _home; | ||
for (uint i; i < _firstMembers.length; i++) { | ||
_govMint(_firstMembers[i], _uri); | ||
_delegate(_firstMembers[i], _firstMembers[i]); | ||
} | ||
} | ||
|
||
|
@@ -127,8 +135,20 @@ contract NFT is | |
emit MetadataUpdated(tokenId, uri, nonce); | ||
} | ||
|
||
/** | ||
* @notice Delegates voting power to another address on home chain | ||
* @dev Overrides ERC721Votes delegate function to add cross-chain functionality | ||
* @param delegatee Address to delegate voting power to | ||
*/ | ||
function delegate(address delegatee) public virtual override onlyHomeChain { | ||
uint256 nonce = _proofStorage.incrementNonce(uint8(OperationType.DELEGATE)); | ||
_delegate(_msgSender(), delegatee); | ||
emit DelegationSynced(_msgSender(), delegatee, nonce); | ||
} | ||
|
||
/** | ||
* @notice Generates proof for NFT operations | ||
* @dev Only callable on home chain | ||
* @param operationType Type of operation | ||
* @param params Operation parameters | ||
* @return Encoded proof data | ||
|
@@ -142,6 +162,31 @@ contract NFT is | |
return ProofHandler.generateProof(address(this), operationType, params, nextNonce); | ||
} | ||
|
||
/** | ||
* @notice Generates proof for delegation | ||
* @dev Only callable on home chain | ||
* @param delegator Address delegating voting power | ||
* @param delegatee Address receiving delegation | ||
* @return Encoded proof data | ||
*/ | ||
function generateDelegationProof( | ||
address delegator, | ||
address delegatee | ||
) external view returns (bytes memory) { | ||
require(block.chainid == home, "Proofs only generated on home chain"); | ||
uint256 nextNonce = _proofStorage.getNextNonce(uint8(OperationType.DELEGATE)); | ||
bytes memory params = abi.encode(delegator, delegatee); | ||
return | ||
ProofHandler.generateProof( | ||
address(this), | ||
uint8(OperationType.DELEGATE), | ||
params, | ||
nextNonce | ||
); | ||
} | ||
|
||
// Claim operations | ||
|
||
/** | ||
* @notice Claims an NFT operation on a foreign chain | ||
* @param proof Proof generated by home chain | ||
|
@@ -163,9 +208,28 @@ contract NFT is | |
(uint256 tokenId, string memory uri) = abi.decode(params, (uint256, string)); | ||
_setTokenURI(tokenId, uri); | ||
emit MetadataUpdated(tokenId, uri, nonce); | ||
} else if (operationType == uint8(OperationType.DELEGATE)) { | ||
(address delegator, address delegatee) = abi.decode(params, (address, address)); | ||
_delegate(delegator, delegatee); | ||
emit DelegationSynced(delegator, delegatee, nonce); | ||
} | ||
} | ||
|
||
/** | ||
* @notice Claims a delegation operation on a foreign chain | ||
* @param proof Proof generated by home chain | ||
*/ | ||
function claimDelegation(bytes memory proof) external { | ||
(uint8 operationType, bytes memory params, uint256 nonce) = ProofHandler | ||
.verifyAndClaimProof(proof, address(this), _proofStorage); | ||
|
||
require(operationType == uint8(OperationType.DELEGATE), "Invalid operation type"); | ||
(address delegator, address delegatee) = abi.decode(params, (address, address)); | ||
|
||
_delegate(delegator, delegatee); | ||
emit DelegationSynced(delegator, delegatee, nonce); | ||
} | ||
|
||
/** | ||
* @notice Internal function for minting without proof verification | ||
* @param to Address to receive token | ||
|
@@ -175,10 +239,19 @@ contract NFT is | |
uint256 tokenId = _nextTokenId++; | ||
_safeMint(to, tokenId); | ||
_setTokenURI(tokenId, uri); | ||
_delegate(to, to); | ||
} | ||
|
||
// Required overrides | ||
|
||
/** | ||
* @notice Updates token data | ||
* @dev Overrides ERC721 _update to make NFTs non-transferable | ||
* @param to Recipient address | ||
* @param tokenId Token ID | ||
* @param auth Address authorized for transfer | ||
* @return Previous owner address | ||
*/ | ||
function _update( | ||
address to, | ||
uint256 tokenId, | ||
|
@@ -188,29 +261,54 @@ contract NFT is | |
return super._update(to, tokenId, auth); | ||
} | ||
|
||
/** | ||
* @notice Increments account balance | ||
* @dev Internal override to maintain compatibility | ||
* @param account Account to update | ||
* @param value Amount to increase by | ||
*/ | ||
function _increaseBalance( | ||
address account, | ||
uint128 value | ||
) internal override(ERC721, ERC721Enumerable, ERC721Votes) { | ||
super._increaseBalance(account, value); | ||
} | ||
|
||
/** | ||
* @notice Gets token URI | ||
* @param tokenId Token ID to query | ||
* @return URI string | ||
*/ | ||
function tokenURI( | ||
uint256 tokenId | ||
) public view override(ERC721, ERC721URIStorage) returns (string memory) { | ||
return super.tokenURI(tokenId); | ||
} | ||
|
||
/** | ||
* @notice Checks interface support | ||
* @param interfaceId Interface identifier to check | ||
* @return bool True if interface is supported | ||
*/ | ||
function supportsInterface( | ||
bytes4 interfaceId | ||
) public view override(ERC721, ERC721Enumerable, ERC721URIStorage) returns (bool) { | ||
return super.supportsInterface(interfaceId); | ||
} | ||
|
||
/** | ||
* @notice Gets current timestamp | ||
* @dev Used for voting snapshots | ||
* @return Current block timestamp | ||
*/ | ||
function clock() public view override returns (uint48) { | ||
return uint48(block.timestamp); | ||
} | ||
|
||
/** | ||
* @notice Gets clock mode description | ||
* @return String indicating timestamp-based voting | ||
*/ | ||
function CLOCK_MODE() public pure override returns (string memory) { | ||
return "mode=timestamp"; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.