diff --git a/core/state/statedb.go b/core/state/statedb.go index 8dbddd3282..014e8a0891 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -646,6 +646,10 @@ func (s *StateDB) ValidDeployer(addr common.Address) bool { return IsWhitelistedDeployer(s, addr) } +func (s *StateDB) ValidDeployerV2(addr common.Address, blockTime uint64, whiteListContract *common.Address) bool { + return IsWhitelistedDeployerV2(s, addr, blockTime, whiteListContract) +} + func (s *StateDB) Blacklisted(contractAddr *common.Address, addr *common.Address) bool { return IsAddressBlacklisted(s, contractAddr, addr) } diff --git a/core/state/statedb_utils.go b/core/state/statedb_utils.go index 87535b5798..e74bef9786 100644 --- a/core/state/statedb_utils.go +++ b/core/state/statedb_utils.go @@ -20,6 +20,10 @@ var ( WHITELISTED: 1, WHITELIST_ALL: 2, } + slotWhitelistDeployerMappingV2 = map[string]uint64{ + WHITELISTED: 53, + WHITELIST_ALL: 58, + } // Contract Infinity slotBlacklistContractMapping = map[string]uint64{ BLACKLISTED: 1, DISABLED: 2, @@ -32,11 +36,45 @@ var ( } ) +// IsWhitelistedDeployer reads the contract storage to check if an address is allow to deploy +func IsWhitelistedDeployerV2(statedb *StateDB, address common.Address, blockTime uint64, whiteListContract *common.Address) bool { + contract := *whiteListContract + whitelistAllSlot := slotWhitelistDeployerMappingV2[WHITELIST_ALL] + whitelistAll := statedb.GetState(contract, GetLocSimpleVariable(whitelistAllSlot)) + + if whitelistAll.Big().Cmp(common.Big1) == 0 { + return true + } + + whitelistedSlot := slotWhitelistDeployerMappingV2[WHITELISTED] + // WhiteListInfo have 2 fields, so we need to plus 1. + // struct WhiteListInfo { + // uint256 expiryTimestamp; + // bool activated; + // } + expiredLoc := GetLocMappingAtKey(address.Hash(), whitelistedSlot) + activatedLoc := common.BigToHash(expiredLoc.Big().Add(expiredLoc.Big(), common.Big1)) + expiredHash := statedb.GetState(contract, expiredLoc) + + activatedHash := statedb.GetState(contract, activatedLoc) + + // (whiteListInfo.activated && block.timestamp < whiteListInfo.expiryTimestamp) + // Compare expiredHash with Blockheader timestamp. + if activatedHash.Big().Cmp(common.Big1) == 0 { + if expiredHash.Big().Cmp(big.NewInt(int64(blockTime))) > 0 { + // Block time still is in expiredTime + return true + } + } + return false +} + // IsWhitelistedDeployer reads the contract storage to check if an address is allow to deploy func IsWhitelistedDeployer(statedb *StateDB, address common.Address) bool { contract := common.HexToAddress(common.WhitelistDeployerSC) whitelistAllSlot := slotWhitelistDeployerMapping[WHITELIST_ALL] whitelistAll := statedb.GetState(contract, GetLocSimpleVariable(whitelistAllSlot)) + if whitelistAll.Big().Cmp(big.NewInt(1)) == 0 { return true } diff --git a/core/vm/evm.go b/core/vm/evm.go index e28a68c0a0..3d4d312c08 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -500,10 +500,17 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, } } } - - if evm.chainRules.IsOdysseusFork && !evm.StateDB.ValidDeployer(caller.Address()) { - captureTraceEarly(ErrExecutionReverted) - return nil, common.Address{}, gas, ErrExecutionReverted + // Handle latest hardfork firstly. + if evm.chainRules.IsAntenna { + if !evm.StateDB.ValidDeployerV2(caller.Address(), evm.Context.Time, evm.ChainConfig().WhiteListDeployerContractV2Address) { + captureTraceEarly(ErrExecutionReverted) + return nil, common.Address{}, gas, ErrExecutionReverted + } + } else if evm.chainRules.IsOdysseusFork { + if !evm.StateDB.ValidDeployer(caller.Address()) { + captureTraceEarly(ErrExecutionReverted) + return nil, common.Address{}, gas, ErrExecutionReverted + } } // Depth check execution. Fail if we're trying to execute above the @@ -517,6 +524,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, return nil, common.Address{}, gas, ErrInsufficientBalance } nonce := evm.StateDB.GetNonce(caller.Address()) + if nonce+1 < nonce { captureTraceEarly(ErrNonceUintOverflow) return nil, common.Address{}, gas, ErrNonceUintOverflow diff --git a/core/vm/interface.go b/core/vm/interface.go index a643e0bd05..c03c5fe93b 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -76,6 +76,7 @@ type StateDB interface { ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) error ValidDeployer(common.Address) bool + ValidDeployerV2(common.Address, uint64, *common.Address) bool Blacklisted(*common.Address, *common.Address) bool } diff --git a/core/vm/statedb_utils_test.go b/core/vm/statedb_utils_test.go new file mode 100644 index 0000000000..fadafa8bc0 --- /dev/null +++ b/core/vm/statedb_utils_test.go @@ -0,0 +1,187 @@ +package vm + +import ( + "strings" + "testing" + "time" + + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" +) + +const ( + constructor = "constructor" + initialize = "initialize" + whitelist = "whitelist" +) + +var ( + logicAbi = `[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ErrInvalidExpirationTime","type":"error"},{"inputs":[],"name":"ErrSentryAttemptsToWhitelistABlacklistUser","type":"error"},{"inputs":[],"name":"ErrSentryAttemptsToWhitelistNewComer","type":"error"},{"inputs":[],"name":"ErrUnwhitelistANewcomer","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"whitelistee","type":"address"}],"name":"DeployerUnwhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"deployer","type":"address"},{"indexed":true,"internalType":"uint256","name":"expireTime","type":"uint256"}],"name":"DeployerWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"status","type":"bool"}],"name":"WhitelistAllChanged","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SENTRY_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllWhitelistedAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"deployer","type":"address"}],"name":"getWhitelistInfo","outputs":[{"components":[{"internalType":"uint256","name":"expiryTimestamp","type":"uint256"},{"internalType":"bool","name":"activated","type":"bool"}],"internalType":"struct IWhitelistDeployerV2.WhiteListInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address[]","name":"sentries","type":"address[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isWhitelistAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"deployer","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"whitelistee","type":"address"}],"name":"unwhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"deployer","type":"address"},{"internalType":"uint256","name":"expiryTimestamp","type":"uint256"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"whitelistAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]` + proxyAbi = `[{"inputs":[{"internalType":"address","name":"_logic","type":"address"},{"internalType":"address","name":"admin_","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"admin_","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"implementation_","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]` +) +var ( + proxyAdminCaller = common.BytesToAddress([]byte("proxy_admin")) + adminCaller = common.BytesToAddress([]byte("admin")) + whitelistedCaller = common.BytesToAddress([]byte("whitelisted")) + whitelistDeployerV2 = `0x608060405234801561001057600080fd5b5061001961001e565b6100de565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811610156100dc576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61129c806100ed6000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c806391d14854116100a2578063a217fddf11610071578063a217fddf1461025a578063a2b21fbe14610262578063b56eebfb146102d9578063ca15c873146102ee578063d547741f1461030157600080fd5b806391d148541461020e578063946d92041461022157806398fc55d8146102345780639a5904271461024757600080fd5b806336568abe116100e957806336568abe1461019d5780633af32abf146101b057806358881877146101c35780637a9ad019146101ce5780639010d07c146101e357600080fd5b806301ffc9a71461011b5780630c9a347114610143578063248a9ca3146101585780632f2ff15d1461018a575b600080fd5b61012e610129366004610e78565b610314565b60405190151581526020015b60405180910390f35b610156610151366004610ea2565b61033f565b005b61017c610166366004610ec4565b6000908152600160208190526040909120015490565b60405190815260200161013a565b610156610198366004610ef9565b610388565b6101566101ab366004610ef9565b6103b3565b61012e6101be366004610f25565b610436565b603a5460ff1661012e565b61017c60008051602061124783398151915281565b6101f66101f1366004610f40565b610493565b6040516001600160a01b03909116815260200161013a565b61012e61021c366004610ef9565b6104ab565b61015661022f366004610f78565b6104d6565b610156610242366004611050565b61064e565b610156610255366004610f25565b6107b8565b61017c600081565b6102bc610270366004610f25565b6040805180820190915260008082526020820152506001600160a01b03166000908152603560209081526040918290208251808401909352805483526001015460ff1615159082015290565b60408051825181526020928301511515928101929092520161013a565b6102e161088a565b60405161013a919061107a565b61017c6102fc366004610ec4565b61089b565b61015661030f366004610ef9565b6108b2565b60006001600160e01b03198216635a05180f60e01b14806103395750610339826108d8565b92915050565b600061034a8161090d565b603a805460ff19168315159081179091556040517ff00cf1f0ddd6809f07fa6905b1b604c167671d7164140306bba41f906a637ff190600090a25050565b600082815260016020819052604090912001546103a48161090d565b6103ae838361091a565b505050565b6001600160a01b03811633146104285760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b610432828261093c565b5050565b6001600160a01b03811660009081526035602090815260408083208151808301909252805482526001015460ff908116151592820192909252603a549091168061048c57508060200151801561048c5750805142105b9392505050565b600082815260026020526040812061048c908361095e565b60009182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b600054610100900460ff16158080156104f65750600054600160ff909116105b806105105750303b158015610510575060005460ff166001145b6105735760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161041f565b6000805460ff191660011790558015610596576000805461ff0019166101001790555b6105a160008461096a565b6105b96000805160206112478339815191528461096a565b815160005b81811015610602576105fa60008051602061124783398151915260001b8583815181106105ed576105ed6110c7565b602002602001015161096a565b6001016105be565b505080156103ae576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b6000805160206112478339815191526106668161090d565b4282101561068757604051635e39e99160e01b815260040160405180910390fd5b600061069381336104ab565b9050801580156106b957506001600160a01b038416600090815260356020526040902054155b156106d75760405163c582584160e01b815260040160405180910390fd5b801580156106eb57506106eb603885610974565b1561070957604051635fe23e4760e11b815260040160405180910390fd5b801561071c5761071a603885610996565b505b604080518082018252848152600160208083018281526001600160a01b038916600090815260359092529390209151825591519101805460ff191691151591909117905561076b603685610974565b61077c5761077a6036856109ab565b505b60405183906001600160a01b038616907f22531653f928681e9a83363bb12d972f8786e8c347e11701a49bbb9f271e8b8f90600090a350505050565b6000805160206112478339815191526107d08161090d565b6001600160a01b03821660009081526035602052604090205461080657604051630c991be760e41b815260040160405180910390fd5b6108116000336104ab565b15610823576108216038836109ab565b505b6001600160a01b0382166000908152603560205260409020600101805460ff19169055610851603683610996565b506040516001600160a01b038316907ff59a1a5f5e0d0f307930cd1547cff18d2a34715a97cbd8c0dc7a3b122c5e8cfc90600090a25050565b606061089660366109c0565b905090565b6000818152600260205260408120610339906109cd565b600082815260016020819052604090912001546108ce8161090d565b6103ae838361093c565b60006001600160e01b03198216637965db0b60e01b148061033957506301ffc9a760e01b6001600160e01b0319831614610339565b61091781336109d7565b50565b6109248282610a30565b60008281526002602052604090206103ae90826109ab565b6109468282610a9b565b60008281526002602052604090206103ae9082610996565b600061048c8383610b02565b610432828261091a565b6001600160a01b0381166000908152600183016020526040812054151561048c565b600061048c836001600160a01b038416610b2c565b600061048c836001600160a01b038416610c1f565b6060600061048c83610c6e565b6000610339825490565b6109e182826104ab565b610432576109ee81610cca565b6109f9836020610cdc565b604051602001610a0a92919061110d565b60408051601f198184030181529082905262461bcd60e51b825261041f91600401611182565b610a3a82826104ab565b6104325760008281526001602081815260408084206001600160a01b0386168086529252808420805460ff19169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b610aa582826104ab565b156104325760008281526001602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000826000018281548110610b1957610b196110c7565b9060005260206000200154905092915050565b60008181526001830160205260408120548015610c15576000610b506001836111cb565b8554909150600090610b64906001906111cb565b9050818114610bc9576000866000018281548110610b8457610b846110c7565b9060005260206000200154905080876000018481548110610ba757610ba76110c7565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610bda57610bda6111e2565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610339565b6000915050610339565b6000818152600183016020526040812054610c6657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610339565b506000610339565b606081600001805480602002602001604051908101604052809291908181526020018280548015610cbe57602002820191906000526020600020905b815481526020019060010190808311610caa575b50505050509050919050565b60606103396001600160a01b03831660145b60606000610ceb8360026111f8565b610cf6906002611217565b67ffffffffffffffff811115610d0e57610d0e610f62565b6040519080825280601f01601f191660200182016040528015610d38576020820181803683370190505b509050600360fc1b81600081518110610d5357610d536110c7565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110610d8257610d826110c7565b60200101906001600160f81b031916908160001a9053506000610da68460026111f8565b610db1906001611217565b90505b6001811115610e29576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110610de557610de56110c7565b1a60f81b828281518110610dfb57610dfb6110c7565b60200101906001600160f81b031916908160001a90535060049490941c93610e228161122f565b9050610db4565b50831561048c5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161041f565b600060208284031215610e8a57600080fd5b81356001600160e01b03198116811461048c57600080fd5b600060208284031215610eb457600080fd5b8135801515811461048c57600080fd5b600060208284031215610ed657600080fd5b5035919050565b80356001600160a01b0381168114610ef457600080fd5b919050565b60008060408385031215610f0c57600080fd5b82359150610f1c60208401610edd565b90509250929050565b600060208284031215610f3757600080fd5b61048c82610edd565b60008060408385031215610f5357600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610f8b57600080fd5b610f9483610edd565b915060208084013567ffffffffffffffff80821115610fb257600080fd5b818601915086601f830112610fc657600080fd5b813581811115610fd857610fd8610f62565b8060051b604051601f19603f83011681018181108582111715610ffd57610ffd610f62565b60405291825284820192508381018501918983111561101b57600080fd5b938501935b828510156110405761103185610edd565b84529385019392850192611020565b8096505050505050509250929050565b6000806040838503121561106357600080fd5b61106c83610edd565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b818110156110bb5783516001600160a01b031683529284019291840191600101611096565b50909695505050505050565b634e487b7160e01b600052603260045260246000fd5b60005b838110156110f85781810151838201526020016110e0565b83811115611107576000848401525b50505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516111458160178501602088016110dd565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516111768160288401602088016110dd565b01602801949350505050565b60208152600082518060208401526111a18160408501602087016110dd565b601f01601f19169190910160400192915050565b634e487b7160e01b600052601160045260246000fd5b6000828210156111dd576111dd6111b5565b500390565b634e487b7160e01b600052603160045260246000fd5b6000816000190483118215151615611212576112126111b5565b500290565b6000821982111561122a5761122a6111b5565b500190565b60008161123e5761123e6111b5565b50600019019056fe5bea60102f2a7acc9e82b1af0e3bd4069661102bb5dd143a6051cd1980dded1ca2646970667358221220b4d9959f15bc892573e6f71b852604f5081ee3b420ea1c54a21fd40b7186e45864736f6c63430008090033` + proxyByteCode = `0x608060405260405162000e9838038062000e9883398101604081905262000026916200049d565b828162000036828260006200004d565b50620000449050826200008a565b505050620005d0565b6200005883620000e5565b600082511180620000665750805b1562000085576200008383836200012760201b620002601760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f620000b562000156565b604080516001600160a01b03928316815291841660208301520160405180910390a1620000e2816200018f565b50565b620000f08162000244565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200014f838360405180606001604052806027815260200162000e7160279139620002f8565b9392505050565b60006200018060008051602062000e5183398151915260001b6200037760201b620002081760201c565b546001600160a01b0316919050565b6001600160a01b038116620001fa5760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b806200022360008051602062000e5183398151915260001b6200037760201b620002081760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b6200025a816200037a60201b6200028c1760201c565b620002be5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401620001f1565b80620002237f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200037760201b620002081760201c565b6060600080856001600160a01b0316856040516200031791906200057d565b600060405180830381855af49150503d806000811462000354576040519150601f19603f3d011682016040523d82523d6000602084013e62000359565b606091505b5090925090506200036d8683838762000389565b9695505050505050565b90565b6001600160a01b03163b151590565b60608315620003fa578251620003f2576001600160a01b0385163b620003f25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620001f1565b508162000406565b6200040683836200040e565b949350505050565b8151156200041f5781518083602001fd5b8060405162461bcd60e51b8152600401620001f191906200059b565b80516001600160a01b03811681146200045357600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200048b57818101518382015260200162000471565b83811115620000835750506000910152565b600080600060608486031215620004b357600080fd5b620004be846200043b565b9250620004ce602085016200043b565b60408501519092506001600160401b0380821115620004ec57600080fd5b818601915086601f8301126200050157600080fd5b81518181111562000516576200051662000458565b604051601f8201601f19908116603f0116810190838211818310171562000541576200054162000458565b816040528281528960208487010111156200055b57600080fd5b6200056e8360208301602088016200046e565b80955050505050509250925092565b60008251620005918184602087016200046e565b9190910192915050565b6020815260008251806020840152620005bc8160408501602087016200046e565b601f01601f19169190910160400192915050565b61087180620005e06000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106fb565b610118565b61005b610093366004610716565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106fb565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b606061028583836040518060600160405280602781526020016108156027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb610492565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a4836104ba565b6000825111806103b15750805b156101c3576103c08383610260565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103ef610368565b604080516001600160a01b03928316815291841660208301520160405180910390a1610154816104fa565b6060600080856001600160a01b03168560405161043791906107c5565b600060405180830381855af49150503d8060008114610472576040519150601f19603f3d011682016040523d82523d6000602084013e610477565b606091505b5091509150610488868383876105a3565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61038c565b6104c381610621565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b03811661055f5760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152608401610331565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b6060831561060f578251610608576001600160a01b0385163b6106085760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610331565b5081610619565b61061983836106b5565b949350505050565b6001600160a01b0381163b61068e5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610331565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610582565b8151156106c55781518083602001fd5b8060405162461bcd60e51b815260040161033191906107e1565b80356001600160a01b03811681146106f657600080fd5b919050565b60006020828403121561070d57600080fd5b610285826106df565b60008060006040848603121561072b57600080fd5b610734846106df565b9250602084013567ffffffffffffffff8082111561075157600080fd5b818601915086601f83011261076557600080fd5b81358181111561077457600080fd5b87602082850101111561078657600080fd5b6020830194508093505050509250925092565b60005b838110156107b457818101518382015260200161079c565b838111156103c05750506000910152565b600082516107d7818460208701610799565b9190910192915050565b6020815260008251806020840152610800816040850160208701610799565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220dfbb6eecea80a23ea461c16e5f8a63f5102b824e0a1a1588bae31fe9b473de3264736f6c63430008090033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564` +) + +func TestValidDeployerV2AfterHardFork(t *testing.T) { + // Init stage + statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + evm, err := newEVM(proxyAdminCaller, statedb) + if err != nil { + t.Fatal(err) + } + evm.Context.Time = uint64(time.Now().Unix()) + // Deploy logic and proxy SC. + _, logicContractWhitelist, _, err := evm.Create(AccountRef(proxyAdminCaller), common.FromHex(whitelistDeployerV2), math.MaxUint64/2, big0) + if (logicContractWhitelist == common.Address{}) { + t.Fatal("Failed for deploying logic Contract") + } + if err != nil { + t.Fatal(err) + } + + smcAbi, err := abi.JSON(strings.NewReader(proxyAbi)) + if err != nil { + t.Fatal(err) + } + + logicSmcAbi, err := abi.JSON(strings.NewReader(logicAbi)) + if err != nil { + t.Fatal(err) + } + + initialisedData, _ := logicSmcAbi.Pack(initialize, adminCaller, []common.Address{common.BytesToAddress([]byte("sentry"))}) + constructorData, _ := smcAbi.Pack("", logicContractWhitelist, proxyAdminCaller, initialisedData) + if constructorData == nil { + t.Fatal("Failed for pack contructor data") + } + + byteCode := append(common.FromHex(proxyByteCode), constructorData...) + _, contractProxyWhiteList, _, err := evm.Create(AccountRef(proxyAdminCaller), byteCode, math.MaxUint64/2, big0) + if err != nil { + t.Fatal(err) + } + + // Test deploying without adding whitelist yet. + evm.chainRules.IsAntenna = true + evm.chainConfig.WhiteListDeployerContractV2Address = &contractProxyWhiteList + + _, _, _, err = evm.Create(AccountRef(whitelistedCaller), byteCode, math.MaxUint64/2, big0) + if err == nil { + t.Fatal("It should not be able for deploying") + } + + // Whitelist and redeploying again. + expiredTime := time.Now() + expiredTime = expiredTime.Add(time.Hour * 7) + whiteListedData, err := logicSmcAbi.Pack("whitelist", whitelistedCaller, new(big.Int).SetInt64(expiredTime.Unix())) + if err != nil { + t.Fatal(err) + } + + ret, _, err := evm.Call(AccountRef(adminCaller), contractProxyWhiteList, whiteListedData, math.MaxUint64/2, big0) + if err != nil { + t.Fatal(err) + } + + iswhiteListedData, err := logicSmcAbi.Pack("isWhitelisted", whitelistedCaller) + if err != nil { + t.Fatal(err) + } + + ret, _, _ = evm.StaticCall(AccountRef(adminCaller), contractProxyWhiteList, iswhiteListedData, 1000000) + if ret == nil { + t.Fatal("The caller is not whitelisted succesfully.") + } + _, _, _, err = evm.Create(AccountRef(whitelistedCaller), byteCode, math.MaxUint64/2, big0) + if err != nil { + t.Fatal(err) + } +} + +func TestValidDeployerV2Expiration(t *testing.T) { + // Init stage + statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + evm, err := newEVM(proxyAdminCaller, statedb) + if err != nil { + t.Fatal(err) + } + evm.Context.Time = uint64(time.Now().Unix()) + // Deploy logic and proxy SC. + _, logicContractWhitelist, _, err := evm.Create(AccountRef(proxyAdminCaller), common.FromHex(whitelistDeployerV2), math.MaxUint64/2, big0) + if (logicContractWhitelist == common.Address{}) { + t.Fatal("Failed for deploying logic Contract") + } + if err != nil { + t.Fatal(err) + } + + smcAbi, err := abi.JSON(strings.NewReader(proxyAbi)) + if err != nil { + t.Fatal(err) + } + + logicSmcAbi, err := abi.JSON(strings.NewReader(logicAbi)) + if err != nil { + t.Fatal(err) + } + + initialisedData, _ := logicSmcAbi.Pack(initialize, adminCaller, []common.Address{common.BytesToAddress([]byte("sentry"))}) + constructorData, _ := smcAbi.Pack("", logicContractWhitelist, proxyAdminCaller, initialisedData) + if constructorData == nil { + t.Fatal("Failed for pack contructor data") + } + + byteCode := append(common.FromHex(proxyByteCode), constructorData...) + _, contractProxyWhiteList, _, err := evm.Create(AccountRef(proxyAdminCaller), byteCode, math.MaxUint64/2, big0) + if err != nil { + t.Fatal(err) + } + + // Test deploying without adding whitelist yet. + evm.chainRules.IsAntenna = true + evm.chainConfig.WhiteListDeployerContractV2Address = &contractProxyWhiteList + + // Whitelist + expiredTime := time.Now() + expiredTime = expiredTime.Add(time.Hour * 7) + whiteListedData, err := logicSmcAbi.Pack("whitelist", whitelistedCaller, new(big.Int).SetInt64(expiredTime.Unix())) + if err != nil { + t.Fatal(err) + } + + ret, _, err := evm.Call(AccountRef(adminCaller), contractProxyWhiteList, whiteListedData, math.MaxUint64/2, big0) + if err != nil { + t.Fatal(err) + } + + iswhiteListedData, err := logicSmcAbi.Pack("isWhitelisted", whitelistedCaller) + if err != nil { + t.Fatal(err) + } + + ret, _, _ = evm.StaticCall(AccountRef(adminCaller), contractProxyWhiteList, iswhiteListedData, 1000000) + if ret == nil { + t.Fatal("The caller is not whitelisted succesfully.") + } + _, _, _, err = evm.Create(AccountRef(whitelistedCaller), byteCode, math.MaxUint64/2, big0) + if err != nil { + t.Fatal(err) + } + + evm.Context.Time = uint64(time.Now().Add(time.Hour * 14).Unix()) + // Deploy with expire time, expected failed + _, _, _, err = evm.Create(AccountRef(whitelistedCaller), byteCode, math.MaxUint64/2, big0) + if err == nil { + t.Fatal("It should be failed when expiring") + } +} diff --git a/genesis/testnet.json b/genesis/testnet.json index cb0455e6c5..66e88bee80 100644 --- a/genesis/testnet.json +++ b/genesis/testnet.json @@ -29,7 +29,9 @@ "puffyBlock": 12254000, "bubaBlock": 14260600, "olekBlock": 16849000, - "shillinBlock": 20268000 + "shillinBlock": 20268000, + "antennaBlock": 20737258, + "whiteListDeployerContractV2Address": "0x50a7e07Aa75eB9C04281713224f50403cA79851F" }, "alloc": { "0x0000000000000000000000000000000000000011": { diff --git a/params/config.go b/params/config.go index 71e025d752..42c8b7ab4f 100644 --- a/params/config.go +++ b/params/config.go @@ -283,21 +283,23 @@ var ( RoninTestnetStakingContractAddress = common.HexToAddress("0x9C245671791834daf3885533D24dce516B763B28") RoninTestnetProfileContractAddress = common.HexToAddress("0x3b67c8D22a91572a6AB18acC9F70787Af04A4043") RoninTestnetFinalityTrackingAddress = common.HexToAddress("0x41aCDFe786171824a037f2Cd6224c5916A58969a") + RoninWhiteListDeployerContractV2Address = common.HexToAddress("0x50a7e07Aa75eB9C04281713224f50403cA79851F") RoninTestnetChainConfig = &ChainConfig{ - ChainID: big.NewInt(2021), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - OdysseusBlock: big.NewInt(3315095), - FenixBlock: big.NewInt(6770400), - BlacklistContractAddress: &RoninTestnetBlacklistContract, - FenixValidatorContractAddress: &RoninTestnetFenixValidatorContractAddress, + ChainID: big.NewInt(2021), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + OdysseusBlock: big.NewInt(3315095), + FenixBlock: big.NewInt(6770400), + BlacklistContractAddress: &RoninTestnetBlacklistContract, + FenixValidatorContractAddress: &RoninTestnetFenixValidatorContractAddress, + WhiteListDeployerContractV2Address: &RoninWhiteListDeployerContractV2Address, Consortium: &ConsortiumConfig{ Period: 3, Epoch: 30, @@ -315,6 +317,7 @@ var ( BubaBlock: big.NewInt(14260600), OlekBlock: big.NewInt(16849000), ShillinBlock: big.NewInt(20268000), + AntennaBlock: big.NewInt(20737258), } // GoerliTrustedCheckpoint contains the light client trusted checkpoint for the Görli test network. @@ -528,9 +531,10 @@ type ChainConfig struct { // Shillin hardfork introduces fast finality ShillinBlock *big.Int `json:"shillinBlock,omitempty"` // Shillin switch block (nil = no fork, 0 = already on activated) - BlacklistContractAddress *common.Address `json:"blacklistContractAddress,omitempty"` // Address of Blacklist Contract (nil = no blacklist) - FenixValidatorContractAddress *common.Address `json:"fenixValidatorContractAddress,omitempty"` // Address of Ronin Contract in the Fenix hardfork (nil = no blacklist) - + AntennaBlock *big.Int `json:"antennaBlock,omitempty"` // AntennaBlock switch block (nil = no fork, 0 = already on activated) + BlacklistContractAddress *common.Address `json:"blacklistContractAddress,omitempty"` // Address of Blacklist Contract (nil = no blacklist) + FenixValidatorContractAddress *common.Address `json:"fenixValidatorContractAddress,omitempty"` // Address of Ronin Contract in the Fenix hardfork (nil = no blacklist) + WhiteListDeployerContractV2Address *common.Address `json:"whiteListDeployerContractV2Address,omitempty"` // Address of Whitelist Ronin Contract V2 (nil = no blacklist) // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"` @@ -629,12 +633,16 @@ func (c *ChainConfig) String() string { if c.ConsortiumV2Contracts != nil { finalityTrackingContract = c.ConsortiumV2Contracts.FinalityTracking } + whiteListDeployerContractV2Address := common.HexToAddress("") + if c.WhiteListDeployerContractV2Address != nil { + whiteListDeployerContractV2Address = *c.WhiteListDeployerContractV2Address + } chainConfigFmt := "{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v " chainConfigFmt += "Petersburg: %v Istanbul: %v, Odysseus: %v, Fenix: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, " chainConfigFmt += "Engine: %v, Blacklist Contract: %v, Fenix Validator Contract: %v, ConsortiumV2: %v, ConsortiumV2.RoninValidatorSet: %v, " - chainConfigFmt += "ConsortiumV2.SlashIndicator: %v, ConsortiumV2.StakingContract: %v, Puffy: %v, Buba: %v, Olek: %v, Shillin: %v, " - chainConfigFmt += "ConsortiumV2.ProfileContract: %v, ConsortiumV2.FinalityTracking: %v}" + chainConfigFmt += "ConsortiumV2.SlashIndicator: %v, ConsortiumV2.StakingContract: %v, Puffy: %v, Buba: %v, Olek: %v, Shillin: %v, Antenna: %v, " + chainConfigFmt += "ConsortiumV2.ProfileContract: %v, ConsortiumV2.FinalityTracking: %v, whiteListDeployerContractV2Address: %v}" return fmt.Sprintf(chainConfigFmt, c.ChainID, @@ -665,8 +673,10 @@ func (c *ChainConfig) String() string { c.BubaBlock, c.OlekBlock, c.ShillinBlock, + c.AntennaBlock, profileContract.Hex(), finalityTrackingContract.Hex(), + whiteListDeployerContractV2Address.Hex(), ) } @@ -780,6 +790,11 @@ func (c *ChainConfig) IsOlek(num *big.Int) bool { return isForked(c.OlekBlock, num) } +// IsAntenna returns whether the num is equals to or larger than the Antenna fork block. +func (c *ChainConfig) IsAntenna(num *big.Int) bool { + return isForked(c.AntennaBlock, num) +} + // IsShillin returns whether the num is equals to or larger than the shillin fork block. func (c *ChainConfig) IsShillin(num *big.Int) bool { return isForked(c.ShillinBlock, num) @@ -919,6 +934,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi if isForkIncompatible(c.ShillinBlock, newcfg.ShillinBlock, head) { return newCompatError("Shillin fork block", c.ShillinBlock, newcfg.ShillinBlock) } + if isForkIncompatible(c.AntennaBlock, newcfg.AntennaBlock, head) { + return newCompatError("Antenna fork block", c.AntennaBlock, newcfg.AntennaBlock) + } return nil } @@ -987,7 +1005,7 @@ type Rules struct { IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon bool - IsOdysseusFork, IsFenix, IsConsortiumV2 bool + IsOdysseusFork, IsFenix, IsConsortiumV2, IsAntenna bool } // Rules ensures c's ChainID is not nil. @@ -1011,5 +1029,6 @@ func (c *ChainConfig) Rules(num *big.Int) Rules { IsOdysseusFork: c.IsOdysseus(num), IsFenix: c.IsFenix(num), IsConsortiumV2: c.IsConsortiumV2(num), + IsAntenna: c.IsAntenna(num), } }