Created
June 8, 2018 21:28
-
-
Save AugustoL/e85a88a241ff4ee6dc66b12390d8dc6f to your computer and use it in GitHub Desktop.
Contracts
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
pragma solidity ^0.4.23; | |
/** | |
* @title Example1 | |
* @dev Contact that receives ETH and release it at a certain time | |
*/ | |
//Task: Find the issue | |
contract Example1 { | |
uint256 public releaseTime; | |
bool public ethClaimed; | |
constructor(uint256 _releaseTime) public { | |
releaseTime = _releaseTime; | |
} | |
// Claim the ETH raised | |
function claimETH() public { | |
uint256 contractBalance = address(this).balance; | |
require(contractBalance > 0, "Balance not enough"); | |
require(now > releaseTime, "Not release time yet"); | |
address(msg.sender).transfer(contractBalance); | |
ethClaimed = true; | |
} | |
// Fallback function | |
function () public payable { | |
} | |
} | |
pragma solidity ^0.4.23; | |
import "./Ownable.sol"; | |
/** | |
* @title Example2 | |
* @dev Contact that receives ETH and release it at a certain time | |
*/ | |
// Task: Change to override Example1, and change _releaseTime | |
contract Example2 is Ownable { | |
uint256 public releaseTime; | |
constructor(uint256 _releaseTime) public payable { | |
releaseTime = _releaseTime; | |
} | |
// Claim the ETH raised | |
function claimETH() public onlyOwner { | |
uint256 contractBalance = address(this).balance; | |
require(contractBalance > 0, "Balance not enough"); | |
require(now > releaseTime, "Not release time yet"); | |
address(msg.sender).transfer(contractBalance); | |
} | |
} | |
pragma solidity ^0.4.23; | |
/** | |
* @title Example3 | |
* @dev Contact that receives ETH and release it at a certain time for any user | |
*/ | |
// Task: keep track of amount deposited and number of users | |
contract Example3 { | |
mapping(address => Balance) public balances; | |
struct Balance { | |
uint256 deposited; | |
uint256 releaseTime; | |
} | |
// Deposit ETH | |
function deposit(uint256 releaseTime) public payable { | |
require(balances[msg.sender].deposited == 0); | |
require(balances[msg.sender].releaseTime == 0); | |
balances[msg.sender].deposited = msg.value; | |
balances[msg.sender].releaseTime = releaseTime; | |
} | |
// Claim the ETH raised | |
function claimETH() public { | |
require(balances[msg.sender].deposited > 0); | |
require(balances[msg.sender].releaseTime > now); | |
address(msg.sender).transfer(balances[msg.sender].deposited); | |
delete balances[msg.sender]; | |
} | |
// Get information about owner | |
function getInfo(address _owner) public view returns( | |
uint256 deposited, uint256 releaseTime | |
) { | |
return(balances[_owner].deposited, balances[_owner].releaseTime); | |
} | |
} | |
pragma solidity ^0.4.23; | |
import "./Example3.sol"; | |
/** | |
* @title Example4 | |
* @dev Contact that receives ETH and release it at a certain time for any user, | |
* the eth deposited can be transfered to another account | |
*/ | |
// Task keep track of amount deposited and number of users, find the bug | |
contract Example4 is Example3 { | |
function transferDeposit(address newOwner) public { | |
require(balances[msg.sender].deposited > 0); | |
require(balances[msg.sender].releaseTime > 0); | |
balances[newOwner].deposited = balances[msg.sender].deposited; | |
balances[newOwner].releaseTime = balances[msg.sender].releaseTime; | |
delete balances[msg.sender]; | |
} | |
} | |
pragma solidity ^0.4.23; | |
import "./Example4.sol"; | |
import "./Ownable.sol"; | |
import "./ECRecovery.sol"; | |
import "./SafeMath.sol"; | |
/** | |
* @title Example5 | |
* @dev Contact that receives ETH and release it at a certain time for any user, | |
* the eth deposited can be transfered to another account | |
*/ | |
// Task: fix it | |
contract Example5 is Example4, Ownable { | |
using SafeMath for uint256; | |
using ECRecovery for bytes32; | |
// Claim the ETH using signatures | |
function claimSignedETH( | |
uint256 value, address owner, bytes signature | |
) public { | |
require(balances[owner].deposited >= value); | |
require(balances[owner].releaseTime > now); | |
bytes32 msgSigned = keccak256(abi.encodePacked(value)); | |
require(owner == msgSigned.recover(signature)); | |
address(msg.sender).transfer(value); | |
balances[msg.sender].deposited = balances[msg.sender].deposited.sub(value); | |
} | |
} | |
pragma solidity ^0.4.23; | |
/** | |
* @title SafeMath | |
* @dev Math operations with safety checks that throw on error | |
*/ | |
library SafeMath { | |
/** | |
* @dev Multiplies two numbers, throws on overflow. | |
*/ | |
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { | |
// Gas optimization: this is cheaper than asserting 'a' not being zero, but the | |
// benefit is lost if 'b' is also tested. | |
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 | |
if (a == 0) { | |
return 0; | |
} | |
c = a * b; | |
assert(c / a == b); | |
return c; | |
} | |
/** | |
* @dev Integer division of two numbers, truncating the quotient. | |
*/ | |
function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
// assert(b > 0); // Solidity automatically throws when dividing by 0 | |
// uint256 c = a / b; | |
// assert(a == b * c + a % b); // There is no case in which this doesn't hold | |
return a / b; | |
} | |
/** | |
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). | |
*/ | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
assert(b <= a); | |
return a - b; | |
} | |
/** | |
* @dev Adds two numbers, throws on overflow. | |
*/ | |
function add(uint256 a, uint256 b) internal pure returns (uint256 c) { | |
c = a + b; | |
assert(c >= a); | |
return c; | |
} | |
} | |
pragma solidity ^0.4.23; | |
/** | |
* @title Ownable | |
* @dev The Ownable contract has an owner address, and provides basic authorization control | |
* functions, this simplifies the implementation of "user permissions". | |
*/ | |
contract Ownable { | |
address public owner; | |
event OwnershipRenounced(address indexed previousOwner); | |
event OwnershipTransferred( | |
address indexed previousOwner, | |
address indexed newOwner | |
); | |
/** | |
* @dev The Ownable constructor sets the original `owner` of the contract to the sender | |
* account. | |
*/ | |
constructor() public { | |
owner = msg.sender; | |
} | |
/** | |
* @dev Throws if called by any account other than the owner. | |
*/ | |
modifier onlyOwner() { | |
require(msg.sender == owner); | |
_; | |
} | |
/** | |
* @dev Allows the current owner to relinquish control of the contract. | |
*/ | |
function renounceOwnership() public onlyOwner { | |
emit OwnershipRenounced(owner); | |
owner = address(0); | |
} | |
/** | |
* @dev Allows the current owner to transfer control of the contract to a newOwner. | |
* @param _newOwner The address to transfer ownership to. | |
*/ | |
function transferOwnership(address _newOwner) public onlyOwner { | |
_transferOwnership(_newOwner); | |
} | |
/** | |
* @dev Transfers control of the contract to a newOwner. | |
* @param _newOwner The address to transfer ownership to. | |
*/ | |
function _transferOwnership(address _newOwner) internal { | |
require(_newOwner != address(0)); | |
emit OwnershipTransferred(owner, _newOwner); | |
owner = _newOwner; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment