Skip to content

Commit

Permalink
feat(registry): Add sepolia registry (#900)
Browse files Browse the repository at this point in the history
  • Loading branch information
mjlescano authored Apr 15, 2024
1 parent 2096706 commit b5969aa
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 134 deletions.
7 changes: 7 additions & 0 deletions packages/registry/cannonfile.sepolia.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
include = ["cannonfile.toml"]

[setting.optimismL1Sender]
defaultValue = "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef"

[setting.optimismL2Receiver]
defaultValue = "0x4200000000000000000000000000000000000007"
11 changes: 11 additions & 0 deletions packages/registry/cannonfile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ defaultValue = "official-registry"
[setting.initialOwner]
defaultValue = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"

# Optimism messenger addresses, taken from: https://docs.optimism.io/chain/addresses
[setting.optimismL1Sender]
defaultValue = "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1"

[setting.optimismL2Receiver]
defaultValue = "0x4200000000000000000000000000000000000007"

[contract.InitialImpl]
artifact = "OwnedUpgradable"
salt = "<%= settings.salt %>"
Expand All @@ -22,6 +29,10 @@ depends = ["contract.InitialImpl"]

[contract.Implementation]
artifact = "CannonRegistry"
args = [
"<%= settings.optimismL1Sender %>", # OptimismL1Sender
"<%= settings.optimismL2Receiver %>", # OptimismL2Receiver
]

[invoke.upgrade_proxy]
target = ["InitialProxy"]
Expand Down
43 changes: 30 additions & 13 deletions packages/registry/contracts/CannonRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import {IOptimismL1Sender} from "./IOptimismL1Sender.sol";
import {IOptimismL2Receiver} from "./IOptimismL2Receiver.sol";

contract CannonRegistry is EfficientStorage, OwnedUpgradable {
IOptimismL1Sender private constant _OPTIMISM_MESSENGER = IOptimismL1Sender(0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1);
IOptimismL2Receiver private constant _OPTIMISM_RECEIVER = IOptimismL2Receiver(0x4200000000000000000000000000000000000007);

using SetUtil for SetUtil.Bytes32Set;

error Unauthorized();
Expand All @@ -38,8 +35,16 @@ contract CannonRegistry is EfficientStorage, OwnedUpgradable {
event PackageUnverify(bytes32 indexed name, address indexed verifier);

uint256 public constant MIN_PACKAGE_NAME_LENGTH = 3;
uint256 public publishFee = 0 wei;
uint256 public registerFee = 0 wei;
uint256 public unused = 0 wei;
uint256 public unused2 = 0 wei;

IOptimismL1Sender private immutable _OPTIMISM_MESSENGER;
IOptimismL2Receiver private immutable _OPTIMISM_RECEIVER;

constructor(address _optimismMessenger, address _optimismtReceiver) {
_OPTIMISM_MESSENGER = IOptimismL1Sender(_optimismMessenger); // IOptimismL1Sender(0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1)
_OPTIMISM_RECEIVER = IOptimismL2Receiver(_optimismtReceiver); // IOptimismL2Receiver(0x4200000000000000000000000000000000000007)
}

function validatePackageName(bytes32 _name) public pure returns (bool) {
// each character must be in the supported charset
Expand Down Expand Up @@ -73,9 +78,18 @@ contract CannonRegistry is EfficientStorage, OwnedUpgradable {
return true;
}

function publishFee() public view returns (uint256) {
return _store().publishFee;
}

function registerFee() public view returns (uint256) {
return _store().registerFee;
}

function setFees(uint256 _publishFee, uint256 _registerFee) external onlyOwner {
publishFee = _publishFee;
registerFee = _registerFee;
Store storage store = _store();
store.publishFee = _publishFee;
store.registerFee = _registerFee;
}

function publish(
Expand All @@ -85,8 +99,10 @@ contract CannonRegistry is EfficientStorage, OwnedUpgradable {
string memory _packageDeployUrl,
string memory _packageMetaUrl
) external payable {
if (msg.value != publishFee) {
revert FeeRequired(publishFee);
Store storage store = _store();

if (msg.value != store.publishFee) {
revert FeeRequired(store.publishFee);
}

if (_packageTags.length == 0 || _packageTags.length > 5) {
Expand All @@ -97,7 +113,7 @@ contract CannonRegistry is EfficientStorage, OwnedUpgradable {
revert InvalidUrl(_packageDeployUrl);
}

Package storage _p = _store().packages[_packageName];
Package storage _p = store.packages[_packageName];
address sender = ERC2771Context.msgSender();

if (!_canPublishPackage(_p, sender)) {
Expand Down Expand Up @@ -139,7 +155,8 @@ contract CannonRegistry is EfficientStorage, OwnedUpgradable {
}

function setPackageOwnership(bytes32 _packageName, address _owner) external payable {
Package storage _p = _store().packages[_packageName];
Store storage store = _store();
Package storage _p = store.packages[_packageName];
address sender = ERC2771Context.msgSender();

if (sender == address(_OPTIMISM_RECEIVER)) {
Expand All @@ -152,8 +169,8 @@ contract CannonRegistry is EfficientStorage, OwnedUpgradable {
}

// package new or old check
if (owner == address(0) && msg.value != registerFee) {
revert FeeRequired(registerFee);
if (owner == address(0) && msg.value != store.registerFee) {
revert FeeRequired(store.registerFee);
} else if (owner == address(0)) {
emit PackageRegistered(_packageName, sender);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/registry/contracts/EfficientStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ contract EfficientStorage {
mapping(bytes16 => string) strings;
mapping(bytes32 => Package) packages;
mapping(address => bool) verifiers;
uint256 publishFee;
uint256 registerFee;
}

struct Package {
Expand Down
33 changes: 0 additions & 33 deletions packages/registry/contracts/Storage.sol

This file was deleted.

7 changes: 5 additions & 2 deletions packages/registry/test/contracts/CannonRegistry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe('CannonRegistry', function () {
)) as TMockOptimismBridge;

const CannonRegistryFactory = await ethers.getContractFactory('CannonRegistry');
const Implementation = await CannonRegistryFactory.deploy();
const Implementation = await CannonRegistryFactory.deploy(MockOPSendBridge.address, MockOPRecvBridge.address);
await Implementation.deployed();

const ProxyFactory = await ethers.getContractFactory('Proxy');
Expand All @@ -60,7 +60,10 @@ describe('CannonRegistry', function () {

before('deploy new implementation', async function () {
const CannonRegistry = await ethers.getContractFactory('CannonRegistry');
newImplementation = (await CannonRegistry.deploy()) as TCannonRegistry;
newImplementation = (await CannonRegistry.deploy(
MockOPSendBridge.address,
MockOPRecvBridge.address
)) as TCannonRegistry;
await newImplementation.deployed();
});

Expand Down
170 changes: 84 additions & 86 deletions packages/website/src/features/Deploy/DisplayedTransaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import {
trim,
} from 'viem';

import type { ReactElement } from 'react';

export function DisplayedTransaction(props: {
contracts?: { [key: string]: { address: Address; abi: any[] } };
txn?: Omit<TransactionRequestBase, 'from'>;
Expand Down Expand Up @@ -64,89 +62,6 @@ export function DisplayedTransaction(props: {
? parsedFunction?.args?.map((v) => v) || [props.txn.data?.slice(10)]
: [];

function encodeArg(type: string, val: string): string {
if (Array.isArray(val)) {
if (!type.endsWith('[]')) {
throw Error(`Invalid arg type "${type}" and val "${val}"`);
}

return `["${val
.map((v) => encodeArg(type.slice(0, -2), v))
.join('", "')}"]`;
}

if (type.startsWith('bytes') && val.startsWith('0x')) {
try {
const b = hexToBytes(val as Hex);
const t = b.findIndex((v) => v < 0x20);
if (b[t] != 0 || b.slice(t).find((v) => v != 0)) {
// this doesn't look like a terminated ascii hex string. leave it as hex
return val;
}

if (t === 0) {
return '';
}

return bytesToString(trim(b, { dir: 'right' }));
} catch (err) {
return val.toString();
}
} else if (type == 'tuple') {
// TODO: use a lib?
return JSON.stringify(val, (_, v) =>
typeof v === 'bigint' ? v.toString() : v
);
} else if (type == 'bool') {
return val ? 'true' : 'false';
} else if (type.startsWith('uint') || type.startsWith('int')) {
return val ? BigInt(val).toString() : '0';
}

return val.toString();
}

function renderInput(type: string, val: string): ReactElement {
if (type === 'tuple') {
return (
<CopyBlock
text={JSON.stringify(JSON.parse(encodeArg(type, val || '')), null, 2)}
language="json"
showLineNumbers={false}
codeBlock
theme={a11yDark}
customStyle={{ fontSize: '14px' }}
/>
);
}

return (
<Input
type="text"
size="sm"
bg="black"
borderColor="whiteAlpha.400"
isReadOnly
_focus={{
boxShadow: 'none !important',
outline: 'none !important',
borderColor: 'whiteAlpha.400 !important',
}}
_focusVisible={{
boxShadow: 'none !important',
outline: 'none !important',
borderColor: 'whiteAlpha.400 !important',
}}
_hover={{
boxShadow: 'none !important',
outline: 'none !important',
borderColor: 'whiteAlpha.400 !important',
}}
value={encodeArg(type, (val as string) || '')}
/>
);
}

if (!props.contracts) {
return <Text>{props.txn?.data}</Text>;
}
Expand Down Expand Up @@ -184,7 +99,7 @@ export function DisplayedTransaction(props: {
</Text>
)}
</FormLabel>
{renderInput(
{_renderInput(
execFuncFragment.inputs[i].type,
execFuncArgs[i]
)}
Expand All @@ -197,3 +112,86 @@ export function DisplayedTransaction(props: {
</Box>
);
}

function _encodeArg(type: string, val: string): string {
if (Array.isArray(val)) {
if (!type.endsWith('[]')) {
throw Error(`Invalid arg type "${type}" and val "${val}"`);
}

return `["${val
.map((v) => _encodeArg(type.slice(0, -2), v))
.join('", "')}"]`;
}

if (type.startsWith('bytes') && val.startsWith('0x')) {
try {
const b = hexToBytes(val as Hex);
const t = b.findIndex((v) => v < 0x20);
if (b[t] != 0 || b.slice(t).find((v) => v != 0)) {
// this doesn't look like a terminated ascii hex string. leave it as hex
return val;
}

if (t === 0) {
return '';
}

return bytesToString(trim(b, { dir: 'right' }));
} catch (err) {
return val.toString();
}
} else if (type == 'tuple') {
// TODO: use a lib?
return JSON.stringify(val, (_, v) =>
typeof v === 'bigint' ? v.toString() : v
);
} else if (type == 'bool') {
return val ? 'true' : 'false';
} else if (type.startsWith('uint') || type.startsWith('int')) {
return val ? BigInt(val).toString() : '0';
}

return val.toString();
}

function _renderInput(type: string, val: string) {
if (type === 'tuple') {
return (
<CopyBlock
text={JSON.stringify(JSON.parse(_encodeArg(type, val || '')), null, 2)}
language="json"
showLineNumbers={false}
codeBlock
theme={a11yDark}
customStyle={{ fontSize: '14px' }}
/>
);
}

return (
<Input
type="text"
size="sm"
bg="black"
borderColor="whiteAlpha.400"
isReadOnly
_focus={{
boxShadow: 'none !important',
outline: 'none !important',
borderColor: 'whiteAlpha.400 !important',
}}
_focusVisible={{
boxShadow: 'none !important',
outline: 'none !important',
borderColor: 'whiteAlpha.400 !important',
}}
_hover={{
boxShadow: 'none !important',
outline: 'none !important',
borderColor: 'whiteAlpha.400 !important',
}}
value={_encodeArg(type, (val as string) || '')}
/>
);
}

0 comments on commit b5969aa

Please sign in to comment.