Skip to content

Commit

Permalink
test(evm): validate eip-7702 deploy flow and permissioned delegation
Browse files Browse the repository at this point in the history
  • Loading branch information
topocount committed Dec 21, 2024
1 parent 61125f3 commit 7f9b7e8
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"test": "forge test -vvv",
"test:ci": "forge test --summary --detailed -vvv",
"coverage": "forge coverage --report lcov --report-file coverage/lcov.info",
"create:intent": "forge script script/solidity/SetupIntents.s.sol:SetupIntents --broadcast -f http://127.0.0.1:8545 --skip-simulation --mnemonics 'test test test test test test test test test test test junk'",
"deploy:core:local": "forge script script/solidity/Deploy.s.sol:CoreDeployer -f http://127.0.0.1:8545 --broadcast --mnemonics \"test test test test test test test test test test test junk\"",
"deploy:modules:local": "forge script script/solidity/Deploy_Modules.s.sol:ModuleBaseDeployer -f http://127.0.0.1:8545 --broadcast --mnemonics \"test test test test test test test test test test test junk\"",
"anvil": "anvil"
Expand Down
2 changes: 1 addition & 1 deletion packages/evm/script/solidity/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ contract CoreDeployer is ScriptUtils {
}

function run() public {
console.log("deploying address: ", vm.addr(vm.envUint("SIGNER_PRIVATE_KEY")));
//console.log("deploying address: ", vm.addr(vm.envUint("SIGNER_PRIVATE_KEY")));
// 1. Deploy Boost registry
address registry = _deployRegistry();
address core = _deployCore(registry);
Expand Down
16 changes: 14 additions & 2 deletions packages/evm/script/solidity/Deploy_Modules.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ contract ModuleBaseDeployer is ScriptUtils {
return BoostRegistry(deployJson.readAddress(".BoostRegistry"));
}

function _getBoostCore() internal returns (BoostCore core) {
string memory path =
string(abi.encodePacked(vm.projectRoot(), "/deploys/", vm.toString(block.chainid), ".json"));
deployJson = vm.readFile(path);
deployJson = deployJsonKey.serialize(deployJson);
if (!vm.keyExistsJson(deployJson, ".BoostCore")) {
revert("No Boost Core deployed: run `pnpm deploy:core:local");
}
return BoostCore(deployJson.readAddress(".BoostCore"));
}

function _deployManagedBudget(BoostRegistry registry) internal returns (address managedBudget) {
bytes memory initCode = type(ManagedBudget).creationCode;
managedBudget = _getCreate2Address(initCode, "");
Expand Down Expand Up @@ -245,10 +256,11 @@ contract ModuleBaseDeployer is ScriptUtils {
function _deployIntentValidator(BoostRegistry registry) internal returns (address intentValidator) {
// Deploy DestinationSettler since it's an input to IntentValidator
bytes memory settlerInitCode = type(DestinationSettler).creationCode;
address settler = _getCreate2Address(settlerInitCode, "");
BoostCore core = _getBoostCore();
address settler = _getCreate2Address(settlerInitCode, abi.encode(core));
console.log("DestinationSettler: ", settler);
deployJson = deployJsonKey.serialize("DestinationSettler", settler);
_deploy2(settlerInitCode, "");
_deploy2(settlerInitCode, abi.encode(core));

bytes memory initCode = type(IntentValidator).creationCode;
intentValidator = _getCreate2Address(initCode, "");
Expand Down
142 changes: 142 additions & 0 deletions packages/evm/script/solidity/SetupIntents.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.24;

import "./Util.s.sol";
import {BoostCore} from "contracts/BoostCore.sol";
import {ExperimentalDelegation} from "contracts/intents/account/ExperimentalDelegation.sol";
import {SignatureVerification} from "contracts/intents/SignatureVerification.sol";
import {ECDSA} from "contracts/intents/utils/ECDSA.sol";

contract SetupIntents is ScriptUtils {
using stdJson for string;

BoostCore core;
ExperimentalDelegation public delegation;
uint256 p256privateKey;
address destinationSettler = 0xd9f723044c28147f744a6A7D85EAb402FC4772E5;
// EIP-7212 compliant deploy from mainnet https://github.com/daimo-eth/p256-verifier
bytes verifierCode =
hex"60e06040523461001a57610012366100c7565b602081519101f35b600080fd5b6040810190811067ffffffffffffffff82111761003b57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60e0810190811067ffffffffffffffff82111761003b57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761003b57604052565b60a08103610193578060201161001a57600060409180831161018f578060601161018f578060801161018f5760a01161018c57815182810181811067ffffffffffffffff82111761015f579061013291845260603581526080356020820152833560203584356101ab565b15610156575060ff6001915b5191166020820152602081526101538161001f565b90565b60ff909161013e565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80fd5b5080fd5b5060405160006020820152602081526101538161001f565b909283158015610393575b801561038b575b8015610361575b6103585780519060206101dc818301938451906103bd565b1561034d57604051948186019082825282604088015282606088015260808701527fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f60a08701527fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551958660c082015260c081526102588161006a565b600080928192519060055afa903d15610345573d9167ffffffffffffffff831161031857604051926102b1857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160185610086565b83523d828585013e5b156102eb57828280518101031261018c5750015190516102e693929185908181890994099151906104eb565b061490565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526001600452fd5b6024827f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b6060916102ba565b505050505050600090565b50505050600090565b507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518310156101c4565b5082156101bd565b507fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325518410156101b6565b7fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90818110801590610466575b8015610455575b61044d577f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b8282818080957fffffffff00000001000000000000000000000000fffffffffffffffffffffffc0991818180090908089180091490565b505050600090565b50801580156103f1575082156103f1565b50818310156103ea565b7f800000000000000000000000000000000000000000000000000000000000000081146104bc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b909192608052600091600160a05260a05193600092811580610718575b61034d57610516838261073d565b95909460ff60c05260005b600060c05112156106ef575b60a05181036106a1575050507f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5957f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2969594939291965b600060c05112156105c7575050505050507fffffffff00000001000000000000000000000000ffffffffffffffffffffffff91506105c260a051610ca2565b900990565b956105d9929394959660a05191610a98565b9097929181928960a0528192819a6105f66080518960c051610722565b61060160c051610470565b60c0528061061b5750505050505b96959493929196610583565b969b5061067b96939550919350916001810361068857507f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5937f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29693610952565b979297919060a05261060f565b6002036106985786938a93610952565b88938893610952565b600281036106ba57505050829581959493929196610583565b9197917ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd0161060f575095508495849661060f565b506106ff6080518560c051610722565b8061070b60c051610470565b60c052156105215761052d565b5060805115610508565b91906002600192841c831b16921c1681018091116104bc5790565b8015806107ab575b6107635761075f91610756916107b3565b92919091610c42565b9091565b50507f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296907f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f590565b508115610745565b919082158061094a575b1561080f57507f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29691507f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5906001908190565b7fb01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a917fffffffff00000001000000000000000000000000ffffffffffffffffffffffff808481600186090894817f94e82e0c1ed3bdb90743191a9c5bbf0d88fc827fd214cc5f0b5ec6ba27673d6981600184090893841561091b575050808084800993840994818460010994828088600109957f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29609918784038481116104bc5784908180867fffffffff00000001000000000000000000000000fffffffffffffffffffffffd0991818580090808978885038581116104bc578580949281930994080908935b93929190565b9350935050921560001461093b5761093291610b6d565b91939092610915565b50506000806000926000610915565b5080156107bd565b91949592939095811580610a90575b15610991575050831580610989575b61097a5793929190565b50600093508392508291508190565b508215610970565b85919294951580610a88575b610a78577fffffffff00000001000000000000000000000000ffffffffffffffffffffffff968703918783116104bc5787838189850908938689038981116104bc5789908184840908928315610a5d575050818880959493928180848196099b8c9485099b8c920999099609918784038481116104bc5784908180867fffffffff00000001000000000000000000000000fffffffffffffffffffffffd0991818580090808978885038581116104bc578580949281930994080908929190565b965096505050509093501560001461093b5761093291610b6d565b9550509150915091906001908190565b50851561099d565b508015610961565b939092821580610b65575b61097a577fffffffff00000001000000000000000000000000ffffffffffffffffffffffff908185600209948280878009809709948380888a0998818080808680097fffffffff00000001000000000000000000000000fffffffffffffffffffffffc099280096003090884808a7fffffffff00000001000000000000000000000000fffffffffffffffffffffffd09818380090898898603918683116104bc57888703908782116104bc578780969481809681950994089009089609930990565b508015610aa3565b919091801580610c3a575b610c2d577fffffffff00000001000000000000000000000000ffffffffffffffffffffffff90818460020991808084800980940991817fffffffff00000001000000000000000000000000fffffffffffffffffffffffc81808088860994800960030908958280837fffffffff00000001000000000000000000000000fffffffffffffffffffffffd09818980090896878403918483116104bc57858503928584116104bc5785809492819309940890090892565b5060009150819081908190565b508215610b78565b909392821580610c9a575b610c8d57610c5a90610ca2565b9182917fffffffff00000001000000000000000000000000ffffffffffffffffffffffff80809581940980099009930990565b5050509050600090600090565b508015610c4d565b604051906020918281019183835283604083015283606083015260808201527fffffffff00000001000000000000000000000000fffffffffffffffffffffffd60a08201527fffffffff00000001000000000000000000000000ffffffffffffffffffffffff60c082015260c08152610d1a8161006a565b600080928192519060055afa903d15610d93573d9167ffffffffffffffff83116103185760405192610d73857fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160185610086565b83523d828585013e5b156102eb57828280518101031261018c5750015190565b606091610d7c56fea2646970667358221220fa55558b04ced380e93d0a46be01bb895ff30f015c50c516e898c341cd0a230264736f6c63430008150033";

string constant deployJsonKey = "deployJsonKey";
string deployJson;

function setUp() public {
vm.etch(address(0x14), verifierCode);
P256KeyGenerator generator = new P256KeyGenerator();
//p256privateKey = generator.generatePrivateKey();
p256privateKey = 100366595829038452957523597440756290436854445761208339940577349703440345778405;
console.log("pk: ", p256privateKey);
core = _getBoostCore();
}

function run() public {
VmSafe.Wallet memory bob = vm.createWallet(
0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97
);
VmSafe.Wallet memory alice = vm.createWallet(
0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6
);
ExperimentalDelegation aliceAbstracted = ExperimentalDelegation(
payable(address(alice.addr))
);
// restart if alice already has a 7702 contract
if (vm.load(alice.addr, bytes32(uint(2))) > 0 ) revert("restart anvil to clear code");
vm.broadcast(alice.privateKey);
delegation = new ExperimentalDelegation(destinationSettler);
(uint256 x, uint256 y) = vm.publicKeyP256(p256privateKey);
SignatureVerification.Key[]
memory keys = new SignatureVerification.Key[](1);
keys[0] = SignatureVerification.Key(
0,
SignatureVerification.KeyType.P256,
ECDSA.PublicKey(x, y)
);

bytes32 digest = keccak256(abi.encode(1, "shiny new wallet", keys));
console.log("digest");
console.logBytes32(digest);
console.log("alice addr: ", alice.addr);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(
alice.privateKey,
keccak256(abi.encode(0, "shiny new wallet", keys))
);

vm.signAndAttachDelegation(address(delegation), alice.privateKey);
vm.broadcast(bob.privateKey);
aliceAbstracted.initialize(
"shiny new wallet",
keys,
ECDSA.Signature(uint256(r), uint256(s), v)
);

aliceAbstracted.getKeys();
SignatureVerification.Key[]
memory nextKeys = new SignatureVerification.Key[](1);
nextKeys[0] = SignatureVerification.Key(
0,
SignatureVerification.KeyType.P256,
ECDSA.PublicKey(x, y)
);

bytes32 hash = keccak256(abi.encode(aliceAbstracted.nonce(), nextKeys));
(r, s) = vm.signP256(p256privateKey, hash);

SignatureVerification.WrappedSignature
memory wrappedSignature = SignatureVerification.WrappedSignature(
0,
ECDSA.Signature(uint256(r), uint256(s), 0),
false,
"0xf00d"
);

console.log("r: ", uint(r));
console.log("s: ", uint(s));
console.logBytes32(hash);
console.logBytes(abi.encode(hash, r, s, x, y));

// prove that we can delegate arbitrary calls using P256 signatures
vm.broadcast(bob.privateKey);
aliceAbstracted.authorize(nextKeys, abi.encodePacked(r, s, bytes1(0)));
}

function _getBoostCore() internal returns (BoostCore) {
string memory path = string(
abi.encodePacked(
vm.projectRoot(),
"/deploys/",
vm.toString(block.chainid),
".json"
)
);
deployJson = vm.readFile(path);
deployJson = deployJsonKey.serialize(deployJson);
if (!vm.keyExistsJson(deployJson, ".BoostCore")) {
revert("No Boost Core deployed: run `pnpm deploy:core:local");
}
return BoostCore(deployJson.readAddress(".BoostCore"));
}
}

contract P256KeyGenerator {
// P256 curve order (n)
uint256 private constant P256_N =
0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;

function generatePrivateKey() public view returns (uint256) {
// Generate random bytes using keccak256
bytes32 randomBytes = keccak256(
abi.encodePacked(
block.timestamp,
block.prevrandao,
msg.sender,
blockhash(block.number - 1)
)
);

// Convert to uint256 and ensure it's within valid range (1 to n-1)
uint256 privateKey = (uint256(randomBytes) % (P256_N - 1)) + 1;

return privateKey;
}
}

0 comments on commit 7f9b7e8

Please sign in to comment.