-
Notifications
You must be signed in to change notification settings - Fork 25
Logic contracts can be "accidentally killed" #320
Comments
Agree on going with (2) for now. Eventually we could use trustless off-chain computation ✨ (e.g. TrueBit) to perform all of these safety checks on contracts. I'm not sure if that would be in App, Directory, or elsewhere though... |
Instead of looking at the raw bytecode (which will always contain raw binary data because of the included metadata), and parsing the source code (which may be a bit fragile), we could traverse the AST (recursively), where a selfdestruct call will show up as an expression with the following fields:
Keep in mind though that a contract may still selfdestruct even if the opcode isn't present by doing a |
Issue Status: 1. Open 2. Started 3. Submitted 4. Done This issue now has a funding of 330.0 DAI (330.0 USD @ $1.0/DAI) attached to it.
|
Issue Status: 1. Open 2. Started 3. Submitted 4. Done Work has been started. These users each claimed they can complete the work by 4 weeks, 1 day from now. Please review their questions below:
Learn more on the Gitcoin Issue Details page. |
I am recognizing some problems within the whole protocol in the git hub tool. |
@mikb456 care to ellaborate? |
Issue Status: 1. Open 2. Started 3. Submitted 4. Done Work has been started. These users each claimed they can complete the work by 7 months, 1 week ago. 1) hardlydifficult has started work. I have an implementation and am working on a pull request, soon. Learn more on the Gitcoin Issue Details page. |
Issue Status: 1. Open 2. Started 3. Submitted 4. Done Work for 330.0 DAI (330.0 USD @ $1.0/DAI) has been submitted by: @vs77bb please take a look at the submitted work:
|
* Warn if contract has a selfdestruct call Fix for #320 We are scanning the AST as suggested by @nventuro * Fixed test fails. I confirmed tests are passing locally this time ;) * Minor style change for consistency. * @spalladino Correct, the original approach did not work. I had misunderstood the structure of the AST. I made the changes you suggested and added a Test. Please let me know if this looks okay. I'm unsure how to address ancestor concern. I wrote a test for this, and commented it out because it fails ATM. If you have a suggestion on how to proceed, I'm happy to take a crack at it. * Addressing feedback I made changes addressing the code review feedback from @spalladino. For the parent implementations, I'm not sure how to go from node ID to the AST. I coded an alternative which is similar. Per the unit test it seems to work. Thoughts on this? * Added a delegatecall warning. Including a unit test for that warning. RE feedback: Changed the for loop style to for-of as suggested. I considered adding a warning for callcode as well, but there is already a message "Warning: "callcode" has been deprecated in favour of "delegatecall"." * Addressing feedback. Updating per the latest feedback. Note that I expect the test will still fail. I'm having trouble locally... When running the test suite, it simply skips the failing tests without message. ".... parseInit √ should not init √ should init with default when init is set √ should init when args is set √ should init with specific function √ should init with specific function and args Contract: add-all script E:\zos-cli2>" And when I try to run the test explicitly it also just terminates without messaging why.. "E:\zos-cli2>C:\Users\lopop\AppData\Roaming\npm\truffle test .\test\scripts\add-all.test.js Using network 'test'. Contract: add-all script E:\zos-cli2>" I tried one-off local tests (for all 4 test cases) and it seems to work fine. "E:\zostest>node ..\zos-cli2\lib\bin\zos-cli add SelfDestruct Compiling contracts Compiling .\contracts\Child.sol... Compiling .\contracts\Nested2.sol... Compiling .\contracts\SelfDestruct.sol... Writing artifacts to .\build\contracts Adding SelfDestruct Contract SelfDestruct (or its parent class) has a selfdestruct call. This is potentially a security risk. Please review and consider removing this call. Successfully written zos.json" I can't repro the fail. I'm unsure how to proceed at the moment. I'm going to set this down and try again later, let me know if you have any tips. thanks. * Fixed test fails. And addressed the feedback from @spalladino
Anything more I could do to help resolve this? |
Just remind me to close the issue associated to the PR :-P Fixed by @HardlyDifficult via #347 |
@vs77bb could you close out the bounty as well? Let me know if there's anything you need from me. |
@spalladino could you please re-open this and assign to @vs77bb for visibility? |
Sorry @HardlyDifficult, but github does not allow me to assign the issue to someone who did not participate in the thread. Have you tried reaching out on gitcoin's Slack? |
@spalladino @HardlyDifficult Apologies this took so long to pay out, great work @HardlyDifficult! (This has been paid out 💸). |
Logic contracts registered in an app are currently open to the same attack as the 2nd Parity Wallet hack. Given that we one of our goals is to make deployments more secure, I'd like to address this at least before the anniversary of the hack (November 7th).
All jokes aside, we are not initializing logic contracts as they are deployed via
zos push
. This will also be true as we move onto the new constructor contracts pattern.These are the options that come to mind to prevent the issue:
1- Push forward zeppelinos/zos-lib#33, which prevents any calls whatsoever to a logic contract. This is the safest solution by far. It requires a new feature altogether in Solidity though, or meddling with the assembly code, which would break verifications, and potentially introduce unexpected bugs. However, even with the new feature, it requires the user to change their contracts to be used with zOS, something we're trying to avoid (unless we modify it automatically from the CLI before deployment).
2- Check the contract code for any SELFDESTRUCT calls. We could either check the binary (which would provide little info the user as where the call is issued, and may also fire some false positives if there is raw data with the same value as the opcode), or the source code of the contract and all its ancestors. The best we can do here is print a warning to the user, indicating that contract could be insecure.
3- Force initialization of logic contracts when registered. This adds a lot of burden to the end user, who needs to provide "fake" params (which will never be used) for every contract to be registered. It also doesn't protect against this problem, since a SELFDESTRUCT in the contract logic could be callable regardless of the initialization parameteres.
I'd go with (2) for the time being. Thoughts?
The text was updated successfully, but these errors were encountered: