Skip to content

Instantly share code, notes, and snippets.

@Dobrokhvalov
Created May 13, 2018 17:41
Show Gist options
  • Save Dobrokhvalov/c05b5fa3ed8f259f335170a0755ef904 to your computer and use it in GitHub Desktop.
Save Dobrokhvalov/c05b5fa3ed8f259f335170a0755ef904 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.4.23+commit.124ca40d.js&optimize=false&gist=
pragma solidity 0.4.23;
/*
* Ownable
*
* Base contract with an owner.
* Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.
*/
contract Ownable {
address public owner;
constructor() public {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
}
pragma solidity ^0.4.23;
import './Owned.sol';
/**
* @title Pausable
* @dev Base contract which allows children to implement an emergency stop mechanism.
*/
contract Pausable is Ownable {
event Pause();
event Unpause();
bool public paused = false;
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*/
modifier whenNotPaused() {
require(!paused);
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*/
modifier whenPaused() {
require(paused);
_;
}
/**
* @dev called by the owner to pause, triggers stopped state
*/
function pause() public onlyOwner whenNotPaused {
paused = true;
emit Pause();
}
/**
* @dev called by the owner to unpause, returns to normal state
*/
function unpause() public onlyOwner whenPaused {
paused = false;
emit Unpause();
}
}
pragma solidity 0.4.23;
contract SafeMath {
function safeMul(uint a, uint b) internal pure returns (uint256) {
uint c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function safeDiv(uint a, uint b) internal pure returns (uint256) {
uint c = a / b;
return c;
}
function safeSub(uint a, uint b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function safeAdd(uint a, uint b) internal pure returns (uint256) {
uint c = a + b;
assert(c >= a);
return c;
}
function max64(uint64 a, uint64 b) internal pure returns (uint64) {
return a >= b ? a : b;
}
function min64(uint64 a, uint64 b) internal pure returns (uint64) {
return a < b ? a : b;
}
function max256(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
function min256(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
}
{
"accounts": {
"account{0}": "0xca35b7d915458ef540ade6068dfe2f44e8fa733c"
},
"linkReferences": {},
"transactions": [
{
"timestamp": 1524832474426,
"record": {
"value": "0",
"parameters": [],
"abi": "0x54a8c0ab653c15bfb48b47fd011ba2b9617af01cb45cab344acd57c924d56798",
"contractName": "Ownable",
"bytecode": "608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060e98061005f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638da5cb5b146044575b600080fd5b348015604f57600080fd5b5060566098565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a723058207a4a4af6a5362a1ad2086ed8ee992eb1f2e4b0bda7d4b6673ad79ba646e9d0750029",
"linkReferences": {},
"name": "",
"type": "constructor",
"from": "account{0}"
}
},
{
"timestamp": 1524832486897,
"record": {
"value": "0",
"parameters": [
"0"
],
"abi": "0xc0d41db1b6c5cd39e7205798b17f08eb6fc41ffc96eeaace0bef52fdf71aa9ab",
"contractName": "VerifiedProxy",
"bytecode": "608060405260008060146101000a81548160ff02191690831515021790555060008060156101000a81548160ff0219169083151502179055506201388060035534801561004b57600080fd5b5060405160208061156683398101806040528101908080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600181905550506114a1806100c56000396000f3006080604052600436106100db576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806307da68f5146100e05780630ee2b0e6146100f7578063260958a51461012257806330d86516146101b05780633e25e837146102425780633f4ba83a146102715780635c975abb146102885780636fb1eb0c146102b75780637297be7f146102e257806375f12b21146103275780638456cb59146103565780638da5cb5b1461036d578063b329bf5c146103c4578063b9e1aa031461040d578063cc8f0b4814610469575b600080fd5b3480156100ec57600080fd5b506100f56104fb565b005b34801561010357600080fd5b5061010c6105bb565b6040518082815260200191505060405180910390f35b34801561012e57600080fd5b5061015160048036038101908080356000191690602001909291905050506105c1565b6040518085600019166000191681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390f35b3480156101bc57600080fd5b506102286004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff169060200190929190803560001916906020019092919080356000191690602001909291905050506106f1565b604051808215151515815260200191505060405180910390f35b34801561024e57600080fd5b50610257610814565b604051808215151515815260200191505060405180910390f35b34801561027d57600080fd5b506102866108e7565b005b34801561029457600080fd5b5061029d6109a5565b604051808215151515815260200191505060405180910390f35b3480156102c357600080fd5b506102cc6109b8565b6040518082815260200191505060405180910390f35b3480156102ee57600080fd5b5061030d600480360381019080803590602001909291905050506109be565b604051808215151515815260200191505060405180910390f35b34801561033357600080fd5b5061033c610aab565b604051808215151515815260200191505060405180910390f35b34801561036257600080fd5b5061036b610abe565b005b34801561037957600080fd5b50610382610b7e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103d057600080fd5b506103f36004803603810190808035600019169060200190929190505050610ba3565b604051808215151515815260200191505060405180910390f35b61044f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035600019169060200190929190505050610d4a565b604051808215151515815260200191505060405180910390f35b34801561047557600080fd5b506104e16004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff16906020019092919080356000191690602001909291908035600019169060200190929190505050611040565b604051808215151515815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561055657600080fd5b600060159054906101000a900460ff1615151561057257600080fd5b6001600060156101000a81548160ff0219169083151502179055507fbedf0f4abfe86d4ffad593d9607fe70e83ea706033d44d24b3b6283cf3fc4f6b60405160405180910390a1565b60025481565b6000806000806105cf61141d565b600460008760001916600019168152602001908152602001600020608060405190810160405290816000820160009054906101000a900460ff1660ff1660ff1681526020016000820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050858160000151826020015183604001518260ff1692509450945094509450509193509193565b60006106fb61141d565b600460008860001916600019168152602001908152602001600020608060405190810160405290816000820160009054906101000a900460ff1660ff1660ff1681526020016000820160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050610808816060015187878787611274565b91505095945050505050565b600080600060149054906101000a900460ff1615151561083357600080fd5b600254905060006002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156108a7573d6000803e3d6000fd5b507f3edf228d54016de2c57c145318c98467681be853eb40b70bc72ffd795550aa26816040518082815260200191505060405180910390a1600191505090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561094257600080fd5b600060149054906101000a900460ff16151561095d57600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600060149054906101000a900460ff1681565b60015481565b600080600060149054906101000a900460ff161515156109dd57600080fd5b600060159054906101000a900460ff161515156109f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610a5457600080fd5b6001549050826001819055507f9f43d788b36e7b67ff4c6a52197dfb4a40cce888efd52a5a7240c1276c85adbf81600154604051808381526020018281526020019250505060405180910390a16001915050919050565b600060159054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b1957600080fd5b600060149054906101000a900460ff16151515610b3557600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060046000846000191660001916815260200190815260200160002090508060000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610c2157600080fd5b60006002811115610c2e57fe5b60ff168160000160009054906101000a900460ff1660ff16141515610c5257600080fd5b600280811115610c5e57fe5b8160000160006101000a81548160ff021916908360ff1602179055508060000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc82600101549081150290604051600060405180830381858888f19350505050158015610ce8573d6000803e3d6000fd5b5082600019163373ffffffffffffffffffffffffffffffffffffffff167f80cbfccdf000bf697891059727332894c6b6fa2090916c79b81127ce49bcad5e83600101546040518082815260200191505060405180910390a36001915050919050565b60008060008060149054906101000a900460ff16151515610d6a57600080fd5b600060159054906101000a900460ff16151515610d8657600080fd5b600060046000866000191660001916815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515610de957600080fd5b610df53a6003546113b3565b9150610e03600154836113e6565b90508034111515610e1357600080fd5b60806040519081016040528060006002811115610e2c57fe5b60ff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001610e5a3484611404565b81526020018673ffffffffffffffffffffffffffffffffffffffff1681525060046000866000191660001916815260200190815260200160002060008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040820151816001015560608201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050610f5c600254826113e6565b600281905550600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002084908060018154018082558091505090600182039060005260206000200160009091929091909150906000191690555083600019163373ffffffffffffffffffffffffffffffffffffffff167f2e2761f646b354a5faab29bd1678d8b4d7c99f316c85f66d8487272a9c186a3c34843a60405180848152602001838152602001828152602001935050505060405180910390a360019250505092915050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561109e57600080fd5b600060149054906101000a900460ff161515156110ba57600080fd5b600060159054906101000a900460ff161515156110d657600080fd5b60046000886000191660001916815260200190815260200160002090506000600281111561110057fe5b60ff168160000160009054906101000a900460ff1660ff1614151561112457600080fd5b6111558160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1687878787611274565b151561116057600080fd5b6001600281111561116d57fe5b8160000160006101000a81548160ff021916908360ff1602179055508573ffffffffffffffffffffffffffffffffffffffff166108fc82600101549081150290604051600060405180830381858888f193505050501580156111d3573d6000803e3d6000fd5b508573ffffffffffffffffffffffffffffffffffffffff168160000160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1688600019167fd4a505bcd31da8ec19eb84a508f0c1ee82e102e5911c3e8b880ad23f865954a784600101546040518082815260200191505060405180910390a4600191505095945050505050565b60008060008660405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140191505060405180910390209150600182878787604051600081526020016040526040518085600019166000191681526020018460ff1660ff1681526020018360001916600019168152602001826000191660001916815260200194505050505060206040516020810390808403906000865af115801561136b573d6000803e3d6000fd5b5050506020604051035190508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16149250505095945050505050565b600080828402905060008414806113d457508284828115156113d157fe5b04145b15156113dc57fe5b8091505092915050565b60008082840190508381101515156113fa57fe5b8091505092915050565b600082821115151561141257fe5b818303905092915050565b608060405190810160405280600060ff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff16815250905600a165627a7a723058206e31a8d552e66137daab38a1bb15469456c09094a651a39fe26d0a2351e4531e0029",
"linkReferences": {},
"name": "",
"type": "constructor",
"from": "account{0}"
}
}
],
"abis": {
"0x54a8c0ab653c15bfb48b47fd011ba2b9617af01cb45cab344acd57c924d56798": [
{
"inputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"constant": true,
"inputs": [],
"name": "owner",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
],
"0xc0d41db1b6c5cd39e7205798b17f08eb6fc41ffc96eeaace0bef52fdf71aa9ab": [
{
"constant": false,
"inputs": [
{
"name": "_transferId",
"type": "bytes32"
}
],
"name": "cancelTransfer",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_newCommissionFee",
"type": "uint256"
}
],
"name": "changeFixedCommissionFee",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_verPubKey",
"type": "address"
},
{
"name": "_transferId",
"type": "bytes32"
}
],
"name": "deposit",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "pause",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "oldCommissionFee",
"type": "uint256"
},
{
"indexed": false,
"name": "newCommissionFee",
"type": "uint256"
}
],
"name": "LogChangeFixedCommissionFee",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "commissionAmount",
"type": "uint256"
}
],
"name": "LogWithdrawCommission",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "transferId",
"type": "bytes32"
},
{
"indexed": true,
"name": "sender",
"type": "address"
},
{
"indexed": true,
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"name": "amount",
"type": "uint256"
}
],
"name": "LogWithdraw",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "address"
},
{
"indexed": true,
"name": "transferId",
"type": "bytes32"
},
{
"indexed": false,
"name": "amount",
"type": "uint256"
}
],
"name": "LogCancel",
"type": "event"
},
{
"constant": false,
"inputs": [],
"name": "stop",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "address"
},
{
"indexed": true,
"name": "transferId",
"type": "bytes32"
},
{
"indexed": false,
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"name": "commission",
"type": "uint256"
},
{
"indexed": false,
"name": "gasPrice",
"type": "uint256"
}
],
"name": "LogDeposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "Pause",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "Stop",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "Unpause",
"type": "event"
},
{
"constant": false,
"inputs": [],
"name": "unpause",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
},
{
"inputs": [
{
"name": "_commissionFee",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"constant": false,
"inputs": [
{
"name": "_transferId",
"type": "bytes32"
},
{
"name": "_recipient",
"type": "address"
},
{
"name": "_v",
"type": "uint8"
},
{
"name": "_r",
"type": "bytes32"
},
{
"name": "_s",
"type": "bytes32"
}
],
"name": "withdraw",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "withdrawCommission",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "commissionFee",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "commissionToWithdraw",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_transferId",
"type": "bytes32"
}
],
"name": "getTransfer",
"outputs": [
{
"name": "id",
"type": "bytes32"
},
{
"name": "status",
"type": "uint256"
},
{
"name": "from",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "owner",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "paused",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "stopped",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_transferId",
"type": "bytes32"
},
{
"name": "_recipient",
"type": "address"
},
{
"name": "_v",
"type": "uint8"
},
{
"name": "_r",
"type": "bytes32"
},
{
"name": "_s",
"type": "bytes32"
}
],
"name": "verifyTransferSignature",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
]
}
}
pragma solidity ^0.4.23;
import './Pausable.sol';
/**
* @title Stoppable
* @dev Base contract which allows children to implement final irreversible stop mechanism.
*/
contract Stoppable is Pausable {
event Stop();
bool public stopped = false;
/**
* @dev Modifier to make a function callable only when the contract is not stopped.
*/
modifier whenNotStopped() {
require(!stopped);
_;
}
/**
* @dev Modifier to make a function callable only when the contract is stopped.
*/
modifier whenStopped() {
require(stopped);
_;
}
/**
* @dev called by the owner to pause, triggers stopped state
*/
function stop() public onlyOwner whenNotStopped {
stopped = true;
emit Stop();
}
}
/**
* @dev Get transfer details.
* @param _transferId address Unique transfer id.
* @return Transfer details (id, status, sender, amount)
function getTransfer(address _transferId)
public
constant
returns (
address id,
uint status, // 0 - active, 1 - completed, 2 - cancelled;
address from, // transfer sender
uint amount) // in wei
{
Transfer memory transfer = transferDct[_transferId];
return (
_transferId,
transfer.status,
transfer.from,
transfer.amount
);
}
/**
* @dev Cancel transfer and get sent ether back. Only transfer sender can
* cancel transfer.
* @param _transferId address Unique transfer id.
* @return True if success.
function cancelTransfer(address _transferId) public returns (bool success) {
Transfer storage transferOrder = transferDct[_transferId];
// only sender can cancel transfer;
require(msg.sender == transferOrder.from);
// only active transfers can be cancelled;
require(transferOrder.status == uint8(Statuses.ACTIVE));
// set transfer's status to cancelled.
transferOrder.status = uint8(Statuses.CANCELLED);
// transfer ether back to sender
transferOrder.from.transfer(transferOrder.amount);
// log cancel event
emit LogCancel(msg.sender, _transferId, transferOrder.amount);
return true;
}
/**
* @dev Verify that address is signed with correct verification private key.
* @param _verPubKey address Verification public key.
* @param _recipient address Signed address.
* @param _v ECDSA signature parameter v.
* @param _r ECDSA signature parameters r.
* @param _s ECDSA signature parameters s.
* @return True if signature is correct.
/
function verifySignature(
address _verPubKey,
address _recipient,
uint8 _v,
bytes32 _r,
bytes32 _s)
private pure returns(bool success)
{
bytes32 prefixedHash = keccak256("\x19Ethereum Signed Message:\n32", _recipient);
address retAddr = ecrecover(prefixedHash, _v, _r, _s);
return retAddr == _verPubKey;
}
/**
* @dev Verify that address is signed with correct private key for
* verification public key assigned to transfer.
* @param _transferId bytes32 Transfer Id.
* @param _recipient address Signed address.
* @param _v ECDSA signature parameter v.
* @param _r ECDSA signature parameters r.
* @param _s ECDSA signature parameters s.
* @return True if signature is correct.
/
function verifyTransferSignature(
address _transferId,
address _recipient,
uint8 _v,
bytes32 _r,
bytes32 _s)
public pure returns(bool success)
{
return (verifySignature(_transferId,
_recipient, _v, _r, _s));
}
/**
* @dev Withdraw transfer to recipient's address if it is correctly signed
* with private key for verification public key assigned to transfer.
*
* @param _transferId bytes32 Transfer Id.
* @param _recipient address Signed address.
* @param _v ECDSA signature parameter v.
* @param _r ECDSA signature parameters r.
* @param _s ECDSA signature parameters s.
* @return True if success.
/
function withdraw(
address _transferId,
address _recipient,
uint8 _v,
bytes32 _r,
bytes32 _s)
public
onlyOwner // only through verifier can withdraw transfer;
whenNotPaused
whenNotStopped
returns (bool success)
{
Transfer storage transferOrder = transferDct[_transferId];
// only active transfers can be withdrawn;
require(transferOrder.status == uint8(Statuses.ACTIVE));
// verifying signature
require(verifySignature(_transferId,
_recipient, _v, _r, _s ));
// set transfer's status to completed.
transferOrder.status = uint8(Statuses.COMPLETED);
// transfer ether to recipient's address
_recipient.transfer(transferOrder.amount);
// log withdraw event
emit LogWithdraw(_transferId, transferOrder.from, _recipient, transferOrder.amount);
return true;
}
// fallback function - do not receive ether by default
function() public payable {
revert();
}
} */
pragma solidity 0.4.23;
import './SafeMath.sol';
import './Stoppable.sol';
/**
* @title Eth2Phone Escrow Contract
* @dev Contract allows to send ether through verifier (owner of contract).
*
* Only verifier can initiate withdrawal to recipient's address.
* Verifier cannot choose recipient's address without
* transit private key generated by sender.
*
* Sender is responsible to provide transit private key
* to recipient off-chain.
*
* Recepient signs address to receive with transit private key and
* provides signed address to verification server.
* (See VerifyTransferSignature method for details.)
*
* Verifier verifies off-chain the recipient in accordance with verification
* conditions (e.g., phone ownership via SMS authentication) and initiates
* withdrawal to the address provided by recipient.
* (See withdraw method for details.)
*
* Verifier charges commission for it's services.
*
* Sender is able to cancel transfer if it's not yet cancelled or withdrawn
* by recipient.
* (See cancelTransfer method for details.)
*/
contract e2pEscrow is Stoppable, SafeMath {
// fixed amount of wei accrued to verifier with each transfer
uint public commissionFee;
// verifier can withdraw this amount from smart-contract
uint public commissionToWithdraw; // in wei
// verifier's address
address public verifier;
/*
* EVENTS
*/
event LogDeposit(
address indexed sender,
address indexed transitAddress,
uint amount,
uint commission
);
event LogCancel(
address indexed sender,
address indexed transitAddress
);
event LogWithdraw(
address indexed sender,
address indexed transitAddress,
address indexed recipient,
uint amount
);
event LogWithdrawCommission(uint commissionAmount);
event LogChangeFixedCommissionFee(
uint oldCommissionFee,
uint newCommissionFee
);
event LogChangeVerifier(
address oldVerifier,
address newVerifier
);
struct Transfer {
address from;
uint amount; // in wei
}
// Mappings of transitAddress => Transfer Struct
mapping (address => Transfer) transferDct;
/**
* @dev Contructor that sets msg.sender as owner (verifier) in Ownable
* and sets verifier's fixed commission fee.
* @param _commissionFee uint Verifier's fixed commission for each transfer
*/
constructor(uint _commissionFee, address _verifier) public {
commissionFee = _commissionFee;
verifier = _verifier;
}
modifier onlyVerifier() {
require(msg.sender == verifier);
_;
}
/**
* @dev Deposit ether to smart-contract and create transfer.
* Transit address is assigned to transfer by sender.
* Recipient should sign withrawal address with the transit private key
*
* @param _transitAddress transit address assigned to transfer.
* @return True if success.
*/
function deposit(address _transitAddress)
public
whenNotPaused
whenNotStopped
payable
returns(bool)
{
// can not override existing transfer
require(transferDct[_transitAddress].amount == 0);
require(msg.value > commissionFee);
// saving transfer details
transferDct[_transitAddress] = Transfer(
msg.sender,
safeSub(msg.value, commissionFee)//amount = msg.value - comission
);
// accrue verifier's commission
commissionToWithdraw = safeAdd(commissionToWithdraw, commissionFee);
// log deposit event
emit LogDeposit(msg.sender, _transitAddress, msg.value, commissionFee);
return true;
}
/**
* @dev Change verifier's fixed commission fee.
* Only owner can change commision fee.
*
* @param _newCommissionFee uint New verifier's fixed commission
* @return True if success.
*/
function changeFixedCommissionFee(uint _newCommissionFee)
public
whenNotPaused
whenNotStopped
onlyOwner
returns(bool success)
{
uint oldCommissionFee = commissionFee;
commissionFee = _newCommissionFee;
emit LogChangeFixedCommissionFee(oldCommissionFee, commissionFee);
return true;
}
/**
* @dev Change verifier's address.
* Only owner can change verifier's address.
*
* @param _newVerifier address New verifier's address
* @return True if success.
*/
function changeVerifier(address _newVerifier)
public
whenNotPaused
whenNotStopped
onlyOwner
returns(bool success)
{
address oldVerifier = verifier;
verifier = _newVerifier;
emit LogChangeVerifier(oldVerifier, verifier);
return true;
}
/**
* @dev Transfer accrued commission to verifier's address.
* @return True if success.
*/
function withdrawCommission()
public
whenNotPaused
returns(bool success)
{
uint commissionToTransfer = commissionToWithdraw;
commissionToWithdraw = 0;
owner.transfer(commissionToTransfer); // owner is verifier
emit LogWithdrawCommission(commissionToTransfer);
return true;
}
/**
* @dev Get transfer details.
* @param _transitAddress transit address assigned to transfer
* @return Transfer details (id, sender, amount)
*/
function getTransfer(address _transitAddress)
public
constant
returns (
address id,
address from, // transfer sender
uint amount) // in wei
{
Transfer memory transfer = transferDct[_transitAddress];
return (
_transitAddress,
transfer.from,
transfer.amount
);
}
/**
* @dev Cancel transfer and get sent ether back. Only transfer sender can
* cancel transfer.
* @param _transitAddress transit address assigned to transfer
* @return True if success.
*/
function cancelTransfer(address _transitAddress) public returns (bool success) {
Transfer memory transferOrder = transferDct[_transitAddress];
// only sender can cancel transfer;
require(msg.sender == transferOrder.from);
delete transferDct[_transitAddress];
// transfer ether to recipient's address
msg.sender.transfer(transferOrder.amount);
// log cancel event
emit LogCancel(msg.sender, _transitAddress);
return true;
}
/**
* @dev Verify that address is signed with correct verification private key.
* @param _transitAddress transit address assigned to transfer
* @param _recipient address Signed address.
* @param _v ECDSA signature parameter v.
* @param _r ECDSA signature parameters r.
* @param _s ECDSA signature parameters s.
* @return True if signature is correct.
*/
function verifySignature(
address _transitAddress,
address _recipient,
uint8 _v,
bytes32 _r,
bytes32 _s)
public pure returns(bool success)
{
bytes32 prefixedHash = keccak256("\x19Ethereum Signed Message:\n32", _recipient);
address retAddr = ecrecover(prefixedHash, _v, _r, _s);
return retAddr == _transitAddress;
}
/**
* @dev Verify that address is signed with correct private key for
* verification public key assigned to transfer.
* @param _transitAddress transit address assigned to transfer
* @param _recipient address Signed address.
* @param _v ECDSA signature parameter v.
* @param _r ECDSA signature parameters r.
* @param _s ECDSA signature parameters s.
* @return True if signature is correct.
*/
function verifyTransferSignature(
address _transitAddress,
address _recipient,
uint8 _v,
bytes32 _r,
bytes32 _s)
public pure returns(bool success)
{
return (verifySignature(_transitAddress,
_recipient, _v, _r, _s));
}
/**
* @dev Withdraw transfer to recipient's address if it is correctly signed
* with private key for verification public key assigned to transfer.
*
* @param _transitAddress transit address assigned to transfer
* @param _recipient address Signed address.
* @param _v ECDSA signature parameter v.
* @param _r ECDSA signature parameters r.
* @param _s ECDSA signature parameters s.
* @return True if success.
*/
function withdraw(
address _transitAddress,
address _recipient,
uint8 _v,
bytes32 _r,
bytes32 _s
)
public
onlyVerifier // only through verifier can withdraw transfer;
whenNotPaused
whenNotStopped
returns (bool success)
{
Transfer memory transferOrder = transferDct[_transitAddress];
// verifying signature
(verifySignature(_transitAddress,
_recipient, _v, _r, _s ));
delete transferDct[_transitAddress];
// transfer ether to recipient's address
_recipient.transfer(transferOrder.amount);
// log withdraw event
emit LogWithdraw(transferOrder.from, _transitAddress, _recipient, transferOrder.amount);
return true;
}
// fallback function - do not receive ether by default
function() public payable {
revert();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment