Last active
December 19, 2017 03:01
-
-
Save evertonfraga/958c34dc326e02e972e5c333f9c639eb to your computer and use it in GitHub Desktop.
Prevent library direct code execution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
This code snippet aims to show how to prevent library methods from being executed directly. | |
That's achieved by baking in the address of the library before it's deployed, then comparing `address(this)` against the saved address within a modifier. | |
A contract/library address is deterministic, so one could inject that in: keccak256(creator_address, nonceValue). | |
Thanks to @pirapira, @chriseth and @arachnid for the idea. | |
*/ | |
pragma solidity ^0.4.18; | |
library SafeDelegateCall { | |
// npm packages required: web3 ethereumjs-util | |
// eth.generateAddress(web3.eth.accounts[0], web3.eth.getTransactionCount(web3.eth.accounts[0]) | |
address public constant bakedAddr = 0x5afede1e6a7eca11000000000000000000000000; | |
// | |
// This modifier prevents library functions to be called directly | |
// | |
modifier only_if_delegatecalled { | |
require(this != bakedAddr); | |
_; | |
} | |
function kill () only_if_delegatecalled public { | |
selfdestruct(msg.sender); | |
} | |
} | |
library UnsafeDelegateCall { | |
// | |
// kill() can be called both as delegatecall and directly, messing up contracts that rely on this one. | |
// | |
function kill() public { | |
selfdestruct(msg.sender); | |
} | |
} | |
contract SafeDelegateCallTest { | |
// | |
// Simply put, it calls selfdestruct on SafeDelegateCallTest instances. | |
// | |
function kill(address from) public returns (bool){ | |
return from.delegatecall(bytes4(keccak256("suicide()"))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment