To test and record the findings of the following:
We use Sentinel service to detect anomilies in the system and sent alert to channels like Slack or Telegram
- Can it detect event emission? What's the success rate? How fast is it?
- Can it detect function call? What's the success rate? How fast is it?
- Can it detect message call (internal function call), i.e., function called by another contract? What's the success rate? How fast is it?
- Can it detect failed message call or function call?
We use Autotask service to respond to alert raised by Sentinel service
- Cant it respond as instructed? for example, pausing the contract. What's the success rate? How fast is it?
UpgradeProxyandUpgradeProxyImplementation- This pair of contracts are used to test upgrade proxy functionality
- can upgrade function call/event be detected?
- can implementation specific function call/event be detected?
- This pair of contracts are used to test upgrade proxy functionality
OneRoleAccessControl- This contract is used to test contract maintenance or allowance setting function calls
OneRoleAccessControlWithTimeLock- This contract is used to test function calls like contract maintenance along with actions guarded by time lock
NOTE:
- EIP1967 upgrade proxy pattern is used
CallProxycontract is used to invoke message call (internal function call).
The above three contracts all have a set of operator roles:
OneRoleAccessControlandOneRoleAccessControlWithTimeLock- Four roles:
moreSecuredOperator,lessSecuredOperator,errandOperatorandsentinel
- Four roles:
UpgradeProxyandUpgradeProxyImplementation- Three roles:
lessSecuredOperator,errandOperatorandsentinel
- Three roles:
Duties of each role:
moreSecuredOperatormanages important tasks such asupgradeImportantDependencyorteardown, and also assigninglessSecuredOperatorandsentinel- Note that tasks categorized as important tasks are tasks that in its worst case jeoperdize users' fund
- so
moreSecuredOperatorshould be the most secured wallet in the system, e.g., a 5-of-5 multisigs
lessSecuredOperatormanages less important tasks such assetAllowanceorsetImportantParam, and also assigningerrandOperator- Note that tasks categorized as less important tasks are tasks that in its worst case halt the system but not jeoperdizing users' fund
setAllowanceorsetImportantParamfunction is modified to lower the damage iflessSecuredOperatoris compromised- for example,
setAllowancecan only allow pre-specified actor instead of arbitrary one to spend from the contract - for example,
setImportantParamhas a bound on the param so it can't be set to arbitrary value that might endanger users' fund
- for example,
lessSecuredOperatorshould be the second most secured wallet in the system, e.g., a 3-of-5 multisigs
- Note that tasks categorized as less important tasks are tasks that in its worst case halt the system but not jeoperdizing users' fund
errandOperatormanages housekeeping tasks such assetErrandParamorblacklist- Note that tasks categorized as housekeeping tasks are tasks that in its worst case halt part of the system but not jeoperdizing users' fund
errandOperatorcan be a less secured wallet in the system, e.g., a 2-of-3 multisigs or a hot/cold wallet
sentinel's only job is to freeze the system by for example,pausethe contract or stop the staking/borrowing/liquidating functions
NOTE:
- Since we use EIP1967 upgrade proxy pattern,
moreSecuredOperatorwill be the admin of the proxy which manages the upgrade of implementation- and hence
moreSecuredOperatorcan not also be an operator in the implementation because admin's call to proxy contract will be intercepted - UUPS pattern will not have this problem
- and hence
- If
setAllowancesets allowance of unexpected token(s),pausethe contract immediately- we would have to maintain the expected token(s) in the
Autotaskscritps- remeber to update the expected token(s) before doing actual upgrade otherwise it would accidentally
pausethe contract once you upgrade
- remeber to update the expected token(s) before doing actual upgrade otherwise it would accidentally
- we would have to maintain the expected token(s) in the
- If
setImportantParamis set to unexpected values,pausethe contract immediately- the same as above, we have to maintain the expected values
- If
upgradeChildupgrade child contract to an unexpected address,pausethe contract immediately- the same as above, we have to maintain the expected address
NOTE:
- The above conditions are transactions that succeed and changed the state of the contract, we do not respond to failed transactions
- So remember to watch for succeeded transactions in
Sentinelservice or filter out failed transactions inAutotaskscripts
- So remember to watch for succeeded transactions in
- Deploy
CallProxycontractnpx hardhat run scripts/deploy/CallProxy.ts --network kovan
- Deploy
UpgradeProxyandUpgradeProxyImplementationcontractsnpx hardhat run scripts/deploy/UpgradeProxy_set.ts --network kovan
- Deploy
OneRoleAccessControlcontractnpx hardhat run scripts/deploy/OneRoleAccessControl.ts --network kovan
- Deploy
OneRoleAccessControlWithTimeLockcontractnpx hardhat run scripts/deploy/OneRoleAccessControlWithTimeLock.ts --network kovan
NOTE: if you deploy new contract instances, remeber to update the contract addresses in READEME.md and ./scripts/utils.ts
After contracts are deployed, go set up Sentinel and Autotask instances.
- Transfer ownership, for example
OneRoleAccessControl.transferOwnernpx hardhat run scripts/transferRoles/transferOwner_OneRoleAccessControl.ts --network kovan- invoke failed function call
npx hardhat run scripts/transferRoles/fail/fail_transferOwner_OneRoleAccessControl.ts --network kovan
OneRoleAccessControlWithTimeLock.setNewOperatornpx hardhat run scripts/transferRoles/setNewOperator_OneRoleAccessControlWithTimeLock.ts --network kovan- invoke failed internal function call
npx hardhat run scripts/transferRoles/fail/fail_internal_setNewOperator_OneRoleAccessControlWithTimeLock.ts --network kovan
- Contract maintenance, for example
OneRoleAccessControlWithTimeLock.blacklistnpx hardhat run scripts/maintenance/blacklist.ts --network kovan- invoke failed function call
npx hardhat run scripts/maintenance/fail/fail_blacklist.ts --network kovan
- Approving spender, for example
OneRoleAccessControlWithTimeLock.authorizenpx hardhat run scripts/allowance/authorize.ts --network kovan- invoke failed internal function call
npx hardhat run scripts/allowance/fail/fail_authorize.ts --network kovan
- Upgrade proxy implementation, for example
TransparentUpgradeableProxy.upgradeTonpx hardhat run scripts/upgradeProxyImpl/upgradeTo_UpgradeProxyImplementation.ts --network kovan- invoke failed internal function call
npx hardhat run scripts/upgradeProxyImpl/fail/fail_internal_upgrade_UpgradeProxyImplementation.ts --network kovan
- Scripts to trigger sentinel, for example
- trigger by
setAllowanceof unexpected token(s)npx hardhat run scripts/allowance/trigger_sentinel/invalid_token_addr_setAllowance.ts --network kovan
- trigger by
upgradeChildto unexpected address(es)npx hardhat run scripts/maintenance/trigger_sentinel/invalid_child_upgradeChild.ts --network kovan
- trigger by
CallProxy0x1E8b65D0562f89A1Bd951ADD5354d9a374dfe550
UpgradeProxy0xd4c037782a1D181701e697ad80aB56A40c6be9Bb
UpgradeProxyImplementation0x1E0D76E9556a8089cdb3822436104378E3572103
OneRoleAccessControl0x4Ed59b1E11E1460f4Ff5c5ae2895d7bd7c93E713
OneRoleAccessControlWithTimeLock0x0d975AEB0ee9EFd0682A303987aF2018e2917189