# 前期准备：

docker pull remixproject/remix-ide

docker run -p 80:80 remixproject/remix-ide

# 0x1.Donation

safemath.sol

``````pragma solidity >=0.4.22 <0.6.0;

/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error
*/

library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring '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;
}

uint256 c = a * b;
require(c / a == b);

return c;
}

/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold

return c;
}

/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;

return c;
}

/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);

return c;
}

/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}``````

``````pragma solidity 0.4.24;

import "../CtfFramework.sol";
import "../../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol";

contract Donation is CtfFramework{

using SafeMath for uint256;

uint256 public funds;

CtfFramework(_ctfLauncher, _player)
{
}

function() external payable ctf{
}

function withdrawDonationsFromTheSuckersWhoFellForIt() external ctf{
msg.sender.transfer(funds);
funds = 0;
}

}``````

# 0x2.Lock Box

``````pragma solidity 0.4.24;

import "../CtfFramework.sol";

contract Lockbox1 is CtfFramework{

uint256 private pin;

CtfFramework(_ctfLauncher, _player)
{
pin = now%10000;
}

function unlock(uint256 _pin) external ctf{
require(pin == _pin, "Incorrect PIN");
}

}``````

now的意思是获取当前时间戳，然后unlock这里还需要获取pin值，pin作为private的变量，无法被外部call，所以可以使用getStorageAt来获取值，这里pin的话是因为framework它有个mapping占了一位，所以是1

# 0x3 Piggy bank

``````pragma solidity 0.4.24;

import "../CtfFramework.sol";
import "..//SafeMath.sol";

contract PiggyBank is CtfFramework{

using SafeMath for uint256;

uint256 public piggyBalance;
string public name;

CtfFramework(_ctfLauncher, _player)
{
name=_name;
owner=msg.sender;
}

function() external payable ctf{
}

modifier onlyOwner(){
require(msg.sender == owner, "Unauthorized: Not Owner");
_;
}

function withdraw(uint256 amount) internal{
piggyBalance = piggyBalance.sub(amount);
msg.sender.transfer(amount);
}

function collectFunds(uint256 amount) public onlyOwner ctf{
require(amount<=piggyBalance, "Insufficient Funds in Contract");
withdraw(amount);
}

}

contract CharliesPiggyBank is PiggyBank{

uint256 public withdrawlCount;

PiggyBank(_ctfLauncher, _player, "Charlie")
{
withdrawlCount = 0;
}

function collectFunds(uint256 amount) public ctf{
require(amount<=piggyBalance, "Insufficient Funds in Contract");
withdraw(amount);
}

}``````

piggybank中只有owner能调用，而前者是继承自piggy板块，那么就把自己的collectfunds的函数覆盖了piggybank中的函数，所以只需要调用合约中的collectfund函数即可解决 