Skip to content

Commit

Permalink
add iotex config and deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
ququzone committed Oct 7, 2023
1 parent 73b5f3f commit c066535
Show file tree
Hide file tree
Showing 15 changed files with 1,596 additions and 13 deletions.
76 changes: 76 additions & 0 deletions contracts/validators/p256/Base64.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

library Base64 {
/**
* @dev Base64 Encoding/Decoding Table
*/
string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";

/**
* @dev Converts a `bytes` to its Bytes64 `string` representation.
*/
function encode(bytes memory data) internal pure returns (string memory) {
/**
* Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
* https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
*/
if (data.length == 0) return "";

// Loads the table into memory
string memory table = _TABLE;

// Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
// and split into 4 numbers of 6 bits.
// The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
// - `data.length + 2` -> Round up
// - `/ 3` -> Number of 3-bytes chunks
// - `4 *` -> 4 characters for each chunk
uint256 newlength = data.length * 8 / 6;
if (data.length % 6 > 0) {
newlength++;
}
string memory result = new string(newlength);

/// @solidity memory-safe-assembly
assembly {
// Prepare the lookup table (skip the first "length" byte)
let tablePtr := add(table, 1)

// Prepare result pointer, jump over length
let resultPtr := add(result, 32)
// let targetLength := add(resultPtr, newlength)

// Run over the input, 3 bytes at a time
for {
let dataPtr := data
let endPtr := add(data, mload(data))
} lt(dataPtr, endPtr) {} {
// Advance 3 bytes
dataPtr := add(dataPtr, 3)
let input := mload(dataPtr)

// To write each character, shift the 3 bytes (18 bits) chunk
// 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
// and apply logical AND with 0x3F which is the number of
// the previous character in the ASCII table prior to the Base64 Table
// The result is then added to the table to get the character to write,
// and finally write it in the result pointer but with a left shift
// of 256 (1 byte) - 8 (1 ASCII char) = 248 bits
mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
resultPtr := add(resultPtr, 1)

mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
resultPtr := add(resultPtr, 1)

mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
resultPtr := add(resultPtr, 1)

mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
resultPtr := add(resultPtr, 1)
}
}

return result;
}
}
20 changes: 19 additions & 1 deletion contracts/validators/p256/P256Validator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity 0.8.19;
import "../../common/Contants.sol";
import "../BaseValidator.sol";
import "./ISecp256r1.sol";
import "./Base64.sol";

contract P256Validator is BaseValidator {
string public constant override NAME = "P256 Validator";
Expand All @@ -24,7 +25,24 @@ contract P256Validator is BaseValidator {
override
returns (uint256 validationData)
{
if (impl.validateSignature(sha256(abi.encode(userOpHash)), signature, pks[account])) {
bytes memory sig;
bytes32 messageHash;
{
(
bytes memory realSig,
bytes memory authenticatorData,
string memory clientDataJSONPre,
string memory clientDataJSONPost
) = abi.decode(signature, (bytes, bytes, string, string));

string memory clientDataJSON =
string.concat(clientDataJSONPre, Base64.encode(bytes.concat(userOpHash)), clientDataJSONPost);
bytes32 clientDataHash = sha256(bytes(clientDataJSON));
messageHash = sha256(bytes.concat(authenticatorData, clientDataHash));
sig = realSig;
}

if (impl.validateSignature(messageHash, sig, pks[account])) {
return 0;
}
return Contants.SIG_VALIDATION_FAILED;
Expand Down
16 changes: 9 additions & 7 deletions deploy/entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ import { DeployFunction } from 'hardhat-deploy/types'
import { HardhatRuntimeEnvironment } from 'hardhat/types'

const deploy: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts } = hre
const { deployments, getNamedAccounts, network } = hre
const { deployer } = await getNamedAccounts()
const { deploy } = deployments

await deploy('EntryPoint', {
from: deployer,
args: [],
log: true,
deterministicDeployment: false,
})
if (network.name == 'dev') {
await deploy('EntryPoint', {
from: deployer,
args: [],
log: true,
deterministicDeployment: false,
})
}
}

deploy.tags = ['entrypoint', 'core']
Expand Down
15 changes: 12 additions & 3 deletions deploy/factory.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import { ethers } from 'hardhat'
import { DeployFunction } from 'hardhat-deploy/types'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import { addresses } from '../src/config'

const deploy: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts } = hre
const { deployments, getNamedAccounts, network } = hre
const { deployer } = await getNamedAccounts()
const { deploy } = deployments

const entryPoint = await ethers.getContract('EntryPoint')
let entryPointAddr = ''
if (network.name == 'dev') {
const entryPoint = await ethers.getContract('EntryPoint')
entryPointAddr = entryPoint.address
} else {
// @ts-ignore
entryPointAddr = addresses[network.name].entrypoint
}

const handler = await ethers.getContract('DefaultCallbackHandler')

await deploy('SmartAccountFactory', {
from: deployer,
args: [entryPoint.address, handler.address],
args: [entryPointAddr, handler.address],
log: true,
deterministicDeployment: true,
})
Expand Down
1 change: 1 addition & 0 deletions deployments/iotex_testnet/.chainId
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4690
214 changes: 214 additions & 0 deletions deployments/iotex_testnet/DefaultCallbackHandler.json

Large diffs are not rendered by default.

273 changes: 273 additions & 0 deletions deployments/iotex_testnet/OwnerSessionKeyValidator.json

Large diffs are not rendered by default.

253 changes: 253 additions & 0 deletions deployments/iotex_testnet/P256Validator.json

Large diffs are not rendered by default.

70 changes: 70 additions & 0 deletions deployments/iotex_testnet/Secp256r1IoTeX.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"address": "0xebB3F7930b044f4F85263e1Ed99490CA1D5414b2",
"abi": [
{
"inputs": [
{
"internalType": "bytes32",
"name": "message",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "signature",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "publicKey",
"type": "bytes"
}
],
"name": "validateSignature",
"outputs": [
{
"internalType": "bool",
"name": "result",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x8232ecc16147392bcd21ca496d6db43423e06407c5b94f11f4dc2dbe27240cc1",
"receipt": {
"to": "0x355BE1cbfFBf803fdb17E0CB207D051cD9816916",
"from": "0x7c029553644F5E9442cb576c1056e0f7663Db1Fa",
"contractAddress": null,
"transactionIndex": 0,
"gasUsed": "184114",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xac3f87707ecb2eaa41abd1a317ab3dd1d9631ff2fc69fb012c8c67d59d233515",
"transactionHash": "0x8232ecc16147392bcd21ca496d6db43423e06407c5b94f11f4dc2dbe27240cc1",
"logs": [],
"blockNumber": 22646251,
"cumulativeGasUsed": "184114",
"status": 1,
"byzantium": true
},
"args": [],
"numDeployments": 1,
"solcInputHash": "e7b5f1c1bc37ac4da0d4db039ee1af4c",
"metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"message\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"}],\"name\":\"validateSignature\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"result\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/validators/p256/Secp256r1IoTeX.sol\":\"Secp256r1IoTeX\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[]},\"sources\":{\"contracts/validators/p256/ISecp256r1.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.19;\\n\\ninterface ISecp256r1 {\\n function validateSignature(bytes32 message, bytes calldata signature, bytes calldata publicKey)\\n external\\n view\\n returns (bool);\\n}\\n\",\"keccak256\":\"0x2c27d09b504eebfad02daf6a774b8df8bf29c51077f288bf6dd5464b4a18d177\",\"license\":\"MIT\"},\"contracts/validators/p256/Secp256r1IoTeX.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\nimport \\\"./ISecp256r1.sol\\\";\\n\\ncontract Secp256r1IoTeX is ISecp256r1 {\\n function validateSignature(bytes32 message, bytes calldata signature, bytes calldata publicKey)\\n external\\n view\\n override\\n returns (bool result)\\n {\\n bytes32 rs0;\\n bytes32 rs1;\\n bytes32 Q0;\\n bytes32 Q1;\\n\\n (rs0, rs1) = abi.decode(signature, (bytes32, bytes32));\\n (Q0, Q1) = abi.decode(publicKey, (bytes32, bytes32));\\n\\n bytes1 out;\\n assembly {\\n // free memory pointer\\n let input := mload(0x40)\\n\\n mstore(input, message)\\n mstore(add(input, 0x20), rs0)\\n mstore(add(input, 0x40), rs1)\\n mstore(add(input, 0x60), \\\"\\\\x04\\\")\\n mstore(add(input, 0x61), Q0)\\n mstore(add(input, 0x81), Q1)\\n let success := staticcall(gas(), 0x8001, input, 0xa1, out, 0x1)\\n switch success\\n case 0 { revert(0x0, 0x0) }\\n default { result := mload(out) }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x584fafd72e5b4c6cfe511f9027bced97255c6189e850ef814e570b698508e2f6\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b506101c3806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ae7e17f014610030575b600080fd5b61004361003e36600461011a565b610057565b604051901515815260200160405180910390f35b600080808080610069888a018a610194565b909450925061007a86880188610194565b809250819350505060006040518b8152856020820152846040820152600160fa1b606082015283606182015282608182015260018260a1836180015afa905080801561002b575050519a9950505050505050505050565b60008083601f8401126100e357600080fd5b50813567ffffffffffffffff8111156100fb57600080fd5b60208301915083602082850101111561011357600080fd5b9250929050565b60008060008060006060868803121561013257600080fd5b85359450602086013567ffffffffffffffff8082111561015157600080fd5b61015d89838a016100d1565b9096509450604088013591508082111561017657600080fd5b50610183888289016100d1565b969995985093965092949392505050565b600080604083850312156101a757600080fd5b5050803592602090910135915056fea164736f6c6343000813000a",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ae7e17f014610030575b600080fd5b61004361003e36600461011a565b610057565b604051901515815260200160405180910390f35b600080808080610069888a018a610194565b909450925061007a86880188610194565b809250819350505060006040518b8152856020820152846040820152600160fa1b606082015283606182015282608182015260018260a1836180015afa905080801561002b575050519a9950505050505050505050565b60008083601f8401126100e357600080fd5b50813567ffffffffffffffff8111156100fb57600080fd5b60208301915083602082850101111561011357600080fd5b9250929050565b60008060008060006060868803121561013257600080fd5b85359450602086013567ffffffffffffffff8082111561015157600080fd5b61015d89838a016100d1565b9096509450604088013591508082111561017657600080fd5b50610183888289016100d1565b969995985093965092949392505050565b600080604083850312156101a757600080fd5b5050803592602090910135915056fea164736f6c6343000813000a",
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
157 changes: 157 additions & 0 deletions deployments/iotex_testnet/SmartAccountFactory.json

Large diffs are not rendered by default.

Loading

0 comments on commit c066535

Please sign in to comment.