forked from greenpill-dev-guild/camp-green
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:greenpill-dev-guild/green-goods int…
…o contracts/attestations
- Loading branch information
Showing
12 changed files
with
638 additions
and
295 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,5 +1,6 @@ | ||
export API_KEY_ALCHEMY="YOUR_API_KEY_ALCHEMY" | ||
export API_KEY_ARBISCAN="YOUR_API_KEY_ARBISCAN" | ||
export API_KEY_ETHERSCAN="YOUR_API_KEY_ETHERSCAN" | ||
export API_KEY_INFURA="YOUR_API_KEY_INFURA" | ||
export PRIVATE_KEY="YOUR_MNEMONIC" | ||
export FOUNDRY_PROFILE="default" |
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 |
---|---|---|
@@ -1,6 +1,7 @@ | ||
ds-test=./node_modules/ds-test/src/ | ||
forge-std=./node_modules/forge-std/src/ | ||
@openzeppelin/contracts=./node_modules/@openzeppelin/contracts/ | ||
@openzeppelin/contracts=lib/tokenbound/lib/openzeppelin-contracts/contracts/ | ||
@openzeppelin/contracts-upgradeable=./node_modules/@openzeppelin/contracts-upgradeable/ | ||
@eas=./node_modules/@ethereum-attestation-service/eas-contracts/contracts/ | ||
@tokenbound=./lib/tokenbound/src/ | ||
erc6551/=lib/tokenbound/lib/erc6551/src/ |
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 |
---|---|---|
@@ -0,0 +1,130 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
/* solhint-disable max-line-length */ | ||
|
||
pragma solidity ^0.8.25; | ||
|
||
import { Script, console } from "forge-std/Script.sol"; | ||
import { AccountProxy } from "@tokenbound/AccountProxy.sol"; | ||
import { AccountGuardian } from "@tokenbound/AccountGuardian.sol"; | ||
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; | ||
import { Create2 } from "@openzeppelin/contracts/utils/Create2.sol"; | ||
|
||
import { GardenToken } from "../src/tokens/Garden.sol"; | ||
import { GardenAccount } from "../src/accounts/Garden.sol"; | ||
import { TOKENBOUND_REGISTRY } from "../src/Constants.sol"; | ||
|
||
contract Deploy is Script { | ||
function run() external { | ||
bytes32 salt = 0x6551655165516551655165516551655165516551655165516551655165516551; | ||
address factory = 0x4e59b44847b379578588920cA78FbF26c0B4956C; | ||
|
||
address tokenboundSafe = 0x1B9Ac97Ea62f69521A14cbe6F45eb24aD6612C19; // ToDo: Deploy with same address on Sepolia | ||
address erc4337EntryPoint = 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789; | ||
address multicallForwarder = 0xcA11bde05977b3631167028862bE2a173976CA11; | ||
|
||
address guardian = Create2.computeAddress( | ||
salt, | ||
keccak256( | ||
abi.encodePacked(type(AccountGuardian).creationCode, abi.encode(tokenboundSafe)) | ||
), | ||
factory | ||
); | ||
address implementation = Create2.computeAddress( | ||
salt, | ||
keccak256( | ||
abi.encodePacked( | ||
type(GardenAccount).creationCode, | ||
abi.encode(erc4337EntryPoint, multicallForwarder, TOKENBOUND_REGISTRY, guardian) | ||
) | ||
), | ||
factory | ||
); | ||
address proxy = Create2.computeAddress( | ||
salt, | ||
keccak256( | ||
abi.encodePacked( | ||
type(AccountProxy).creationCode, abi.encode(guardian, implementation) | ||
) | ||
), | ||
factory | ||
); | ||
|
||
// Deploy AccountGuardian | ||
if (guardian.code.length == 0) { | ||
vm.startBroadcast(); | ||
new AccountGuardian{salt: salt}(tokenboundSafe); | ||
vm.stopBroadcast(); | ||
|
||
console.log("AccountGuardian:", guardian, "(deployed)"); | ||
} else { | ||
console.log("AccountGuardian:", guardian, "(exists)"); | ||
} | ||
|
||
// Deploy Account implementation | ||
if (implementation.code.length == 0) { | ||
vm.startBroadcast(); | ||
new GardenAccount{salt: salt}( | ||
erc4337EntryPoint, | ||
multicallForwarder, | ||
TOKENBOUND_REGISTRY, | ||
guardian | ||
); | ||
vm.stopBroadcast(); | ||
|
||
console.log("GardenAccount:", implementation, "(deployed)"); | ||
} else { | ||
console.log("GardenAccount:", implementation, "(exists)"); | ||
} | ||
|
||
// Deploy AccountProxy | ||
if (proxy.code.length == 0) { | ||
vm.startBroadcast(); | ||
new AccountProxy{salt: salt}(guardian, implementation); | ||
vm.stopBroadcast(); | ||
|
||
console.log("AccountProxy:", proxy, "(deployed)"); | ||
} else { | ||
console.log("AccountProxy:", proxy, "(exists)"); | ||
} | ||
|
||
console.log("\nVerification Commands:\n"); | ||
console.log( | ||
"AccountGuardian: forge verify-contract --num-of-optimizations 200 --chain-id", | ||
block.chainid, | ||
guardian, | ||
string.concat( | ||
"src/AccountGuardian.sol:AccountGuardian --constructor-args $(cast abi-encode \"constructor(address)\" ", | ||
Strings.toHexString(tokenboundSafe), | ||
")\n" | ||
) | ||
); | ||
console.log( | ||
"GardenAccount: forge verify-contract --num-of-optimizations 200 --chain-id", | ||
block.chainid, | ||
implementation, | ||
string.concat( | ||
"src/GardenAccount.sol:GardenAccount --constructor-args $(cast abi-encode \"constructor(address,address,address,address)\" ", | ||
Strings.toHexString(erc4337EntryPoint), | ||
" ", | ||
Strings.toHexString(multicallForwarder), | ||
" ", | ||
Strings.toHexString(TOKENBOUND_REGISTRY), | ||
" ", | ||
Strings.toHexString(guardian), | ||
")\n" | ||
) | ||
); | ||
console.log( | ||
"AccountProxy: forge verify-contract --num-of-optimizations 200 --chain-id", | ||
block.chainid, | ||
proxy, | ||
string.concat( | ||
"src/AccountProxy.sol:AccountProxy --constructor-args $(cast abi-encode \"constructor(address,address)\" ", | ||
Strings.toHexString(guardian), | ||
" ", | ||
Strings.toHexString(implementation), | ||
")\n" | ||
) | ||
); | ||
} | ||
} |
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 |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity >=0.8.25; | ||
|
||
import { AccountV3Upgradable } from "@tokenbound/AccountV3Upgradable.sol"; | ||
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; | ||
|
||
error NotGardenOwner(); | ||
error TransferNotStarted(); | ||
error NotGoodTransferResolver(); | ||
|
||
contract GardenAccount is AccountV3Upgradable, Initializable { | ||
address public communityToken; | ||
string public name; | ||
|
||
mapping(address gardener => bool isGardener) private gardeners; | ||
mapping(address operator => bool isOperator) private gardenOperators; | ||
|
||
constructor( | ||
address erc4337EntryPoint, | ||
address multicallForwarder, | ||
address erc6551Registry, | ||
address guardian | ||
) AccountV3Upgradable(erc4337EntryPoint, multicallForwarder, erc6551Registry, guardian) {} | ||
|
||
function initialize( | ||
address _communityToken, | ||
string calldata _name, | ||
address[] calldata _gardeners, | ||
address[] calldata _gardenOperators) external initializer { | ||
communityToken = _communityToken; | ||
name = _name; | ||
|
||
for (uint256 i = 0; i < _gardeners.length; i++) { | ||
gardeners[_gardeners[i]] = true; | ||
} | ||
|
||
for (uint256 i = 0; i < _gardenOperators.length; i++) { | ||
gardenOperators[_gardenOperators[i]] = true; | ||
} | ||
} | ||
|
||
function updateName(string memory _name) external { | ||
if (_isValidSigner(msg.sender, "")) { | ||
revert NotGardenOwner(); | ||
} | ||
|
||
name = _name; | ||
} | ||
|
||
function addGardener(address gardener) external { | ||
if (_isValidSigner(msg.sender, "")) { | ||
revert NotGardenOwner(); | ||
} | ||
|
||
gardeners[gardener] = true; | ||
} | ||
|
||
function removeGardener(address gardener) external { | ||
if (_isValidSigner(msg.sender, "")) { | ||
revert NotGardenOwner(); | ||
} | ||
|
||
gardeners[gardener] = false; | ||
} | ||
|
||
function addGardenOperator(address operator) external { | ||
if (_isValidSigner(msg.sender, "")) { | ||
revert NotGardenOwner(); | ||
} | ||
|
||
gardenOperators[operator] = true; | ||
} | ||
|
||
function removeGardenOperator(address operator) external { | ||
if (_isValidSigner(msg.sender, "")) { | ||
revert NotGardenOwner(); | ||
} | ||
|
||
gardenOperators[operator] = false; | ||
} | ||
} |
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 |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.25; | ||
|
||
interface IERC6551Registry { | ||
event AccountCreated( | ||
address account, | ||
address implementation, | ||
uint256 chainId, | ||
address tokenContract, | ||
uint256 tokenId, | ||
uint256 salt | ||
); | ||
|
||
function createAccount( | ||
address implementation, | ||
uint256 chainId, | ||
address tokenContract, | ||
uint256 tokenId, | ||
uint256 seed, | ||
bytes calldata initData | ||
) external returns (address); | ||
|
||
function account( | ||
address implementation, | ||
uint256 chainId, | ||
address tokenContract, | ||
uint256 tokenId, | ||
uint256 salt | ||
) external view returns (address); | ||
} |
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 |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.25; | ||
|
||
import {TOKENBOUND_REGISTRY} from "../Constants.sol"; | ||
import {IERC6551Registry} from "../interfaces/IERC6551Registry.sol"; | ||
|
||
error InvalidChainId(); | ||
|
||
library TBALib { | ||
function createAccount(address implmentation, address tokenContract, uint256 tokenId) external returns (address) { | ||
address account; | ||
|
||
if (block.chainid == 42161) { | ||
account = IERC6551Registry(TOKENBOUND_REGISTRY).createAccount( | ||
implmentation, | ||
42161, | ||
tokenContract, | ||
tokenId, | ||
7, | ||
"" | ||
); | ||
|
||
} else if (block.chainid == 11155111) { | ||
account = IERC6551Registry(TOKENBOUND_REGISTRY).createAccount( | ||
implmentation, | ||
11155111, | ||
tokenContract, | ||
tokenId, | ||
7, | ||
"" | ||
); | ||
} else { | ||
revert InvalidChainId(); | ||
} | ||
|
||
return account; | ||
} | ||
|
||
function getAccount(address implmentation, address tokenContract, uint256 tokenId) external view returns (address) { | ||
address account; | ||
|
||
if (block.chainid == 42161) { | ||
account = IERC6551Registry(TOKENBOUND_REGISTRY).account( | ||
implmentation, | ||
42161, | ||
tokenContract, | ||
tokenId, | ||
7 | ||
); | ||
|
||
} else if (block.chainid == 11155111) { | ||
account = IERC6551Registry(TOKENBOUND_REGISTRY).account( | ||
implmentation, | ||
11155111, | ||
tokenContract, | ||
tokenId, | ||
7 | ||
); | ||
} else { | ||
revert InvalidChainId(); | ||
} | ||
|
||
return account; | ||
} | ||
} |
Oops, something went wrong.