Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use create2 in BridgeCreator #265

Merged
merged 38 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d451b72
docs: add note regarding reorg
gzeoneth Nov 18, 2024
a0e169b
wip: use create2
godzillaba Nov 18, 2024
2d02667
edit comment
godzillaba Nov 18, 2024
80b32f0
start over
godzillaba Nov 18, 2024
a3cb5ef
use create2 in bridge creator
godzillaba Nov 18, 2024
97e7b6f
require rollup exists
godzillaba Nov 18, 2024
855bd7a
fix tests
godzillaba Nov 18, 2024
827169f
fix lint
godzillaba Nov 18, 2024
b7f71a7
Revert "docs: add note regarding reorg"
godzillaba Nov 18, 2024
df6fb6a
remove unnecessary args from salt
godzillaba Nov 18, 2024
73e93ae
fmt
godzillaba Nov 18, 2024
743444f
put the salt args back
godzillaba Nov 18, 2024
1d091e2
refactor: move hardcoded value to config
gzeoneth Nov 26, 2024
fa91157
refactor: minimumAssertionPeriod and validatorAfkBlocks in bold upgra…
gzeoneth Nov 26, 2024
9e6fa38
perf: remove onchain verification
gzeoneth Dec 2, 2024
d709ef5
chore: update sigs
gzeoneth Dec 2, 2024
19c507d
Merge branch 'bold-merge' into move-to-config
gzeoneth Dec 9, 2024
7cafdae
refactor: remove hardcode in rollup initialize
gzeoneth Dec 9, 2024
f4d06c0
chore: update example
gzeoneth Dec 9, 2024
ac1fdda
Merge branch 'bold-merge' into move-to-config
gzeoneth Dec 9, 2024
da85e5a
test: new config param
gzeoneth Dec 9, 2024
21663d8
Merge branch 'move-to-config' into blk-278-fix-bridgecreator-reorg-issue
gzeoneth Dec 9, 2024
89b020a
fix: format
gzeoneth Dec 9, 2024
9df578e
fix: BridgeTemplates
gzeoneth Dec 9, 2024
69c2b06
fix: memory
gzeoneth Dec 9, 2024
8715541
fix: format test
gzeoneth Dec 9, 2024
ba68b99
Merge branch 'move-to-config' into blk-278-fix-bridgecreator-reorg-issue
gzeoneth Dec 9, 2024
853b085
feat: use msg.data hash as salt
gzeoneth Dec 9, 2024
be1a90b
Merge branch 'bold-merge' into move-to-config
gzeoneth Dec 9, 2024
d4edc4f
Merge remote-tracking branch 'origin/move-to-config' into blk-278-fix…
gzeoneth Dec 9, 2024
31e1f06
test: fix
gzeoneth Dec 9, 2024
760bca6
test: fix config
gzeoneth Dec 9, 2024
8e18c0b
Merge branch 'move-to-config' into blk-278-fix-bridgecreator-reorg-issue
gzeoneth Dec 9, 2024
ca06fd4
fix: slither
gzeoneth Dec 9, 2024
ffb2469
Merge branch 'bold-merge' into blk-278-fix-bridgecreator-reorg-issue
gzeoneth Dec 10, 2024
b1c3a49
refactor: bridge creator create2Salt
gzeoneth Dec 10, 2024
8af0e4e
chore: remove unintended change
gzeoneth Dec 10, 2024
8110988
chore: slither
gzeoneth Dec 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions scripts/boldUpgradeCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ export interface Config {
stakeAmt: BigNumber
miniStakeAmounts: BigNumber[]
chainId: number
minimumAssertionPeriod: number
validatorAfkBlocks: number
disableValidatorWhitelist: boolean
maxDataSize: number
blockLeafSize: number
Expand Down
4 changes: 4 additions & 0 deletions scripts/config.ts.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ export const config = {
owner: '0x1234123412341234123412341234123412341234',
loserStakeEscrow: ethers.constants.AddressZero,
chainId: ethers.BigNumber.from('13331370'),
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
chainConfig:
'{"chainId":13331370,"homesteadBlock":0,"daoForkBlock":null,"daoForkSupport":true,"eip150Block":0,"eip150Hash":"0x0000000000000000000000000000000000000000000000000000000000000000","eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0,"istanbulBlock":0,"muirGlacierBlock":0,"berlinBlock":0,"londonBlock":0,"clique":{"period":0,"epoch":0},"arbitrum":{"EnableArbOS":true,"AllowDebugPrecompiles":false,"DataAvailabilityCommittee":false,"InitialArbOSVersion":10,"InitialChainOwner":"0x1234123412341234123412341234123412341234","GenesisBlockNum":0}}',
minimumAssertionPeriod: ethers.BigNumber.from('75'),
validatorAfkBlocks: ethers.BigNumber.from('201600'),
genesisBlockNum: ethers.BigNumber.from('0'),
sequencerInboxMaxTimeVariation: {
delayBlocks: ethers.BigNumber.from('7200'),
Expand Down
2 changes: 2 additions & 0 deletions scripts/files/configs/arb1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export const arb1: Config = {
stakeAmt: parseEther('3600'),
miniStakeAmounts: [parseEther('0'), parseEther('555'), parseEther('79')],
chainId: 42161,
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
disableValidatorWhitelist: true,
blockLeafSize: 2 ** 26,
bigStepLeafSize: 2 ** 19,
Expand Down
2 changes: 2 additions & 0 deletions scripts/files/configs/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export const local: Config = {
parseEther('1'),
],
chainId: 412346,
minimumAssertionPeriod: 0,
validatorAfkBlocks: 201600,
disableValidatorWhitelist: true,
blockLeafSize: 1048576,
bigStepLeafSize: 512,
Expand Down
2 changes: 2 additions & 0 deletions scripts/files/configs/nova.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export const nova: Config = {
stakeAmt: parseEther('1'),
miniStakeAmounts: [parseEther('0'), parseEther('1'), parseEther('1')],
chainId: 42170,
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
disableValidatorWhitelist: false,
blockLeafSize: 2 ** 26, // leaf sizes same as arb1
bigStepLeafSize: 2 ** 19,
Expand Down
2 changes: 2 additions & 0 deletions scripts/files/configs/sepolia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export const sepolia: Config = {
stakeAmt: parseEther('36'), // 1/100th of arb1, same for mini stakes
miniStakeAmounts: [parseEther('0'), parseEther('5.5'), parseEther('0.79')],
chainId: 421614,
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
disableValidatorWhitelist: false,
blockLeafSize: 2 ** 26, // leaf sizes same as arb1
bigStepLeafSize: 2 ** 19,
Expand Down
2 changes: 2 additions & 0 deletions scripts/rollupCreation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ async function _getDevRollupConfig(
loserStakeEscrow: ethers.constants.AddressZero,
chainId: JSON.parse(chainConfig)['chainId'],
chainConfig: chainConfig,
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
genesisAssertionState: {}, // AssertionState
genesisInboxCount: 0,
miniStakeValues: [
Expand Down
2 changes: 1 addition & 1 deletion slither.db.json

Large diffs are not rendered by default.

28 changes: 9 additions & 19 deletions src/rollup/BOLDUpgradeAction.sol
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ contract BOLDUpgradeAction {
address public immutable STAKE_TOKEN;
uint256 public immutable STAKE_AMOUNT;
uint256 public immutable CHAIN_ID;
uint256 public immutable MINIMUM_ASSERTION_PERIOD;
uint64 public immutable VALIDATOR_AFK_BLOCKS;

bool public immutable DISABLE_VALIDATOR_WHITELIST;
uint64 public immutable CHALLENGE_GRACE_PERIOD_BLOCKS;
address public immutable MINI_STAKE_AMOUNTS_STORAGE;
Expand Down Expand Up @@ -223,6 +226,8 @@ contract BOLDUpgradeAction {
uint256 stakeAmt;
uint256[] miniStakeAmounts;
uint256 chainId;
uint256 minimumAssertionPeriod;
uint64 validatorAfkBlocks;
bool disableValidatorWhitelist;
uint256 blockLeafSize;
uint256 bigStepLeafSize;
Expand Down Expand Up @@ -296,6 +301,8 @@ contract BOLDUpgradeAction {
IMPL_CHALLENGE_MANAGER = implementations.challengeManager;

CHAIN_ID = settings.chainId;
MINIMUM_ASSERTION_PERIOD = settings.minimumAssertionPeriod;
VALIDATOR_AFK_BLOCKS = settings.validatorAfkBlocks;
CONFIRM_PERIOD_BLOCKS = settings.confirmPeriodBlocks;
CHALLENGE_PERIOD_BLOCKS = settings.challengePeriodBlocks;
STAKE_TOKEN = settings.stakeToken;
Expand Down Expand Up @@ -373,6 +380,8 @@ contract BOLDUpgradeAction {
loserStakeEscrow: EXCESS_STAKE_RECEIVER, // additional funds get sent to the l1 timelock
chainId: CHAIN_ID,
chainConfig: "", // we can use an empty chain config it wont be used in the rollup initialization because we check if the rei is already connected there
minimumAssertionPeriod: MINIMUM_ASSERTION_PERIOD,
validatorAfkBlocks: VALIDATOR_AFK_BLOCKS,
miniStakeValues: ConstantArrayStorage(MINI_STAKE_AMOUNTS_STORAGE).array(),
sequencerInboxMaxTimeVariation: maxTimeVariation,
layerZeroBlockEdgeHeight: BLOCK_LEAF_SIZE,
Expand Down Expand Up @@ -433,17 +442,6 @@ contract BOLDUpgradeAction {
PROXY_ADMIN_SEQUENCER_INBOX.upgrade(sequencerInbox, IMPL_SEQUENCER_INBOX);
}

// verify
require(
PROXY_ADMIN_SEQUENCER_INBOX.getProxyImplementation(sequencerInbox)
== IMPL_SEQUENCER_INBOX,
"DelayBuffer: new seq inbox implementation not set"
);
require(
ISequencerInbox(SEQ_INBOX).isDelayBufferable() == IS_DELAY_BUFFERABLE,
"DelayBuffer: isDelayBufferable not set"
);

(uint256 delayBlocks, uint256 futureBlocks, uint256 delaySeconds, uint256 futureSeconds) =
ISequencerInbox(SEQ_INBOX).maxTimeVariation();

Expand All @@ -465,14 +463,6 @@ contract BOLDUpgradeAction {
})
);

// verify
(uint256 _delayBlocks, uint256 _futureBlocks, uint256 _delaySeconds, uint256 _futureSeconds)
= ISequencerInbox(SEQ_INBOX).maxTimeVariation();
require(_delayBlocks == delayBlocks, "DelayBuffer: delayBlocks");
require(_delaySeconds == delaySeconds, "DelayBuffer: delaySeconds");
require(_futureBlocks == futureBlocks, "DelayBuffer: futureBlocks");
require(_futureSeconds == futureSeconds, "DelayBuffer: futureSeconds");

ISequencerInbox(SEQ_INBOX).updateRollupAddress();
}

Expand Down
36 changes: 31 additions & 5 deletions src/rollup/BridgeCreator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ contract BridgeCreator is Ownable {
event TemplatesUpdated();
event ERC20TemplatesUpdated();

error RollupCodeEmpty();

struct BridgeTemplates {
IBridge bridge;
ISequencerInbox sequencerInbox;
Expand Down Expand Up @@ -65,17 +67,22 @@ contract BridgeCreator is Ownable {
}

function _createBridge(
bytes32 create2Salt,
address adminProxy,
BridgeTemplates memory templates,
bool isDelayBufferable
) internal returns (BridgeContracts memory) {
BridgeContracts memory frame;
frame.bridge = IBridge(
address(new TransparentUpgradeableProxy(address(templates.bridge), adminProxy, ""))
address(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.bridge), adminProxy, ""
)
)
);
frame.sequencerInbox = ISequencerInbox(
address(
new TransparentUpgradeableProxy(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(
isDelayBufferable
? templates.delayBufferableSequencerInbox
Expand All @@ -87,15 +94,25 @@ contract BridgeCreator is Ownable {
)
);
frame.inbox = IInboxBase(
address(new TransparentUpgradeableProxy(address(templates.inbox), adminProxy, ""))
address(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.inbox), adminProxy, ""
)
)
);
frame.rollupEventInbox = IRollupEventInbox(
address(
new TransparentUpgradeableProxy(address(templates.rollupEventInbox), adminProxy, "")
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.rollupEventInbox), adminProxy, ""
)
)
);
frame.outbox = IOutbox(
address(new TransparentUpgradeableProxy(address(templates.outbox), adminProxy, ""))
address(
new TransparentUpgradeableProxy{salt: create2Salt}(
address(templates.outbox), adminProxy, ""
)
)
);
return frame;
}
Expand All @@ -107,11 +124,20 @@ contract BridgeCreator is Ownable {
ISequencerInbox.MaxTimeVariation calldata maxTimeVariation,
BufferConfig calldata bufferConfig
) external returns (BridgeContracts memory) {
// make sure the rollup exists
// otherwise the rollup creator could be DOSed by frontrunning
if (rollup.code.length == 0) {
revert RollupCodeEmpty();
}

// use create2 salt to ensure deterministic addresses
bytes32 create2Salt = keccak256(msg.data);
gzeoneth marked this conversation as resolved.
Show resolved Hide resolved
// create delay bufferable sequencer inbox if threshold is non-zero
bool isDelayBufferable = bufferConfig.threshold != 0;

// create ETH-based bridge if address zero is provided for native token, otherwise create ERC20-based bridge
BridgeContracts memory frame = _createBridge(
create2Salt,
adminProxy,
nativeToken == address(0) ? ethBasedTemplates : erc20BasedTemplates,
isDelayBufferable
Expand Down
2 changes: 2 additions & 0 deletions src/rollup/Config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ struct Config {
address loserStakeEscrow;
uint256 chainId;
string chainConfig;
uint256 minimumAssertionPeriod;
uint64 validatorAfkBlocks;
uint256[] miniStakeValues;
ISequencerInbox.MaxTimeVariation sequencerInboxMaxTimeVariation;
uint256 layerZeroBlockEdgeHeight;
Expand Down
8 changes: 4 additions & 4 deletions src/rollup/RollupAdminLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ contract RollupAdminLogic is RollupCore, IRollupAdmin, DoubleLogicUUPSUpgradeabl
chainId = config.chainId;
baseStake = config.baseStake;
wasmModuleRoot = config.wasmModuleRoot;
// A little over 15 minutes
minimumAssertionPeriod = 75;
// ValidatorAfkBlocks is defaulted to 28 days assuming a 12 seconds block time.
// minimumAssertionPeriod was defaulted to 75 which is a little over 15 minutes
minimumAssertionPeriod = config.minimumAssertionPeriod;
// ValidatorAfkBlocks was defaulted to 201600 which is 28 days assuming a 12 seconds block time.
// Since it can take 14 days under normal circumstances to confirm an assertion, this means
// the validators will have been inactive for a further 14 days before the whitelist is removed.
validatorAfkBlocks = 201600;
validatorAfkBlocks = config.validatorAfkBlocks;
challengeGracePeriodBlocks = config.challengeGracePeriodBlocks;

// loser stake is now sent directly to loserStakeEscrow, it must not
Expand Down
2 changes: 2 additions & 0 deletions test/Rollup.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ contract RollupTest is Test {
baseStake: BASE_STAKE,
chainId: 0,
chainConfig: "{}",
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
confirmPeriodBlocks: uint64(CONFIRM_PERIOD_BLOCKS),
owner: owner,
sequencerInboxMaxTimeVariation: ISequencerInbox.MaxTimeVariation({
Expand Down
2 changes: 2 additions & 0 deletions test/e2e/orbitChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,8 @@ describe('Orbit Chain', () => {
chainId: ethers.BigNumber.from('433333'),
chainConfig:
'{"chainId":433333,"homesteadBlock":0,"daoForkBlock":null,"daoForkSupport":true,"eip150Block":0,"eip150Hash":"0x0000000000000000000000000000000000000000000000000000000000000000","eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0,"istanbulBlock":0,"muirGlacierBlock":0,"berlinBlock":0,"londonBlock":0,"clique":{"period":0,"epoch":0},"arbitrum":{"EnableArbOS":true,"AllowDebugPrecompiles":false,"DataAvailabilityCommittee":false,"InitialArbOSVersion":10,"InitialChainOwner":"0x72f7EEedF02C522242a4D3Bdc8aE6A8583aD7c5e","GenesisBlockNum":0}}',
minimumAssertionPeriod: 75,
validatorAfkBlocks: 201600,
genesisAssertionState: genesisAssertionState, // AssertionState
genesisInboxCount: 0,
miniStakeValues: [
Expand Down
28 changes: 28 additions & 0 deletions test/foundry/BridgeCreator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ contract BridgeCreatorTest is Test {
max: type(uint64).max,
replenishRateInBasis: 0
});

// give the rollup some code, otherwise it will revert
vm.etch(rollup, hex"0123");

BridgeCreator.BridgeContracts memory contracts =
creator.createBridge(proxyAdmin, rollup, nativeToken, timeVars, bufferConfig);
(
Expand Down Expand Up @@ -196,6 +200,9 @@ contract BridgeCreatorTest is Test {
replenishRateInBasis: 0
});

// give the rollup some code, otherwise it will revert
vm.etch(rollup, hex"0123");

BridgeCreator.BridgeContracts memory contracts =
creator.createBridge(proxyAdmin, rollup, nativeToken, timeVars, bufferConfig);
(
Expand Down Expand Up @@ -245,4 +252,25 @@ contract BridgeCreatorTest is Test {
assertEq(address(outbox.bridge()), address(bridge), "Invalid bridge ref");
assertEq(address(outbox.rollup()), rollup, "Invalid rollup ref");
}

function test_emptyRollupShouldRevert() external {
address proxyAdmin = address(300);
address rollup = address(301);
address nativeToken =
address(new ERC20PresetFixedSupply("Appchain Token", "App", 1_000_000, address(this)));
ISequencerInbox.MaxTimeVariation memory timeVars =
ISequencerInbox.MaxTimeVariation(10, 20, 30, 40);
BufferConfig memory bufferConfig = BufferConfig({
threshold: type(uint64).max,
max: type(uint64).max,
replenishRateInBasis: 0
});

// give the proxy admin some code
vm.etch(proxyAdmin, hex"0123");

// empty rollup should revert
vm.expectRevert(BridgeCreator.RollupCodeEmpty.selector);
creator.createBridge(proxyAdmin, rollup, nativeToken, timeVars, bufferConfig);
}
}
27 changes: 23 additions & 4 deletions test/foundry/RollupCreator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ contract RollupCreatorTest is Test {
baseStake: 1000,
chainId: 1337,
chainConfig: "abc",
confirmPeriodBlocks: 20,
minimumAssertionPeriod: 75,
validatorAfkBlocks: 1234,
confirmPeriodBlocks: 567,
owner: rollupOwner,
sequencerInboxMaxTimeVariation: timeVars,
stakeToken: address(token),
Expand Down Expand Up @@ -184,6 +186,12 @@ contract RollupCreatorTest is Test {
batchPosterManager,
"Invalid batch poster manager"
);
assertEq(
rollup.validatorAfkBlocks(), config.validatorAfkBlocks, "Invalid validatorAfkBlocks"
);
assertEq(
rollup.confirmPeriodBlocks(), config.confirmPeriodBlocks, "Invalid confirmPeriodBlocks"
);

// check proxy admin for non-rollup contracts
address proxyAdminExpectedAddress = computeCreateAddress(address(rollupCreator), 1);
Expand Down Expand Up @@ -285,7 +293,9 @@ contract RollupCreatorTest is Test {
baseStake: 1000,
chainId: 1337,
chainConfig: "abc",
confirmPeriodBlocks: 20,
minimumAssertionPeriod: 75,
validatorAfkBlocks: 1234,
confirmPeriodBlocks: 567,
owner: rollupOwner,
sequencerInboxMaxTimeVariation: timeVars,
stakeToken: address(token),
Expand Down Expand Up @@ -332,11 +342,12 @@ contract RollupCreatorTest is Test {
vm.stopPrank();

_postCreateERC20RollupChecks(
rollupAddress, batchPosterManager, nativeToken, validators, batchPosters
config, rollupAddress, batchPosterManager, nativeToken, validators, batchPosters
);
}

function _postCreateERC20RollupChecks(
Config memory config,
address rollupAddress,
address batchPosterManager,
address nativeToken,
Expand Down Expand Up @@ -371,6 +382,12 @@ contract RollupCreatorTest is Test {
batchPosterManager,
"Invalid batch poster manager"
);
assertEq(
rollup.validatorAfkBlocks(), config.validatorAfkBlocks, "Invalid validatorAfkBlocks"
);
assertEq(
rollup.confirmPeriodBlocks(), config.confirmPeriodBlocks, "Invalid confirmPeriodBlocks"
);

// native token check
IBridge bridge = RollupCore(address(rollupAddress)).bridge();
Expand Down Expand Up @@ -456,7 +473,9 @@ contract RollupCreatorTest is Test {
baseStake: 1000,
chainId: 1337,
chainConfig: "abc",
confirmPeriodBlocks: 20,
minimumAssertionPeriod: 75,
validatorAfkBlocks: 1234,
confirmPeriodBlocks: 567,
owner: rollupOwner,
sequencerInboxMaxTimeVariation: timeVars,
stakeToken: address(token),
Expand Down
2 changes: 1 addition & 1 deletion test/signatures/RollupAdminLogic
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"getStakerAddress(uint64)": "6ddd3744",
"getValidators()": "b7ab4db5",
"inbox()": "fb0e722b",
"initialize((uint64,address,uint256,bytes32,address,address,uint256,string,uint256[],(uint256,uint256,uint256,uint256),uint256,uint256,uint256,((bytes32[2],uint64[2]),uint8,bytes32),uint256,address,uint8,uint64,(uint64,uint64,uint64)),(address,address,address,address,address,address,address,address,address))": "9e7e6aa7",
"initialize((uint64,address,uint256,bytes32,address,address,uint256,string,uint256,uint64,uint256[],(uint256,uint256,uint256,uint256),uint256,uint256,uint256,((bytes32[2],uint64[2]),uint8,bytes32),uint256,address,uint8,uint64,(uint64,uint64,uint64)),(address,address,address,address,address,address,address,address,address))": "0ee5ef0c",
"isFirstChild(bytes32)": "30836228",
"isPending(bytes32)": "e531d8c7",
"isStaked(address)": "6177fd18",
Expand Down
Loading
Loading