Skip to content

Commit

Permalink
Merge pull request #9 from conr2d/compatible-with-solidity-5
Browse files Browse the repository at this point in the history
Fix to compatible with solidity 5
  • Loading branch information
chatch authored Feb 5, 2019
2 parents e5370b0 + 281d878 commit daf3590
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 59 deletions.
13 changes: 6 additions & 7 deletions contracts/HashedTimelock.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pragma solidity ^0.4.24;
pragma experimental "v0.5.0";
pragma solidity ^0.5.0;

/**
* @title Hashed Timelock Contracts (HTLCs) on Ethereum ETH.
Expand All @@ -20,7 +19,7 @@ pragma experimental "v0.5.0";
* back with this function.
*/
contract HashedTimelock {

event LogHTLCNew(
bytes32 indexed contractId,
address indexed sender,
Expand All @@ -33,8 +32,8 @@ contract HashedTimelock {
event LogHTLCRefund(bytes32 indexed contractId);

struct LockContract {
address sender;
address receiver;
address payable sender;
address payable receiver;
uint amount;
bytes32 hashlock; // sha-2 sha256 hash
uint timelock; // UNIX timestamp seconds - locked UNTIL this time
Expand Down Expand Up @@ -92,7 +91,7 @@ contract HashedTimelock {
* @return contractId Id of the new HTLC. This is needed for subsequent
* calls.
*/
function newContract(address _receiver, bytes32 _hashlock, uint _timelock)
function newContract(address payable _receiver, bytes32 _hashlock, uint _timelock)
external
payable
fundsSent
Expand Down Expand Up @@ -199,7 +198,7 @@ contract HashedTimelock {
)
{
if (haveContract(_contractId) == false)
return;
return (address(0), address(0), 0, 0, 0, false, false, 0);
LockContract storage c = contracts[_contractId];
return (c.sender, c.receiver, c.amount, c.hashlock, c.timelock,
c.withdrawn, c.refunded, c.preimage);
Expand Down
11 changes: 5 additions & 6 deletions contracts/HashedTimelockERC20.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pragma solidity ^0.4.24;
pragma experimental "v0.5.0";
pragma solidity ^0.5.0;

import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";

Expand Down Expand Up @@ -51,7 +50,7 @@ contract HashedTimelockERC20 {
modifier tokensTransferable(address _token, address _sender, uint _amount) {
require(_amount > 0, "token amount must be > 0");
require(
ERC20(_token).allowance(_sender, this) >= _amount,
ERC20(_token).allowance(_sender, address(this)) >= _amount,
"token allowance must be >= amount"
);
_;
Expand Down Expand Up @@ -136,9 +135,9 @@ contract HashedTimelockERC20 {
revert();

// This contract becomes the temporary owner of the tokens
if (!ERC20(_tokenContract).transferFrom(msg.sender, this, _amount))
if (!ERC20(_tokenContract).transferFrom(msg.sender, address(this), _amount))
revert();

contracts[contractId] = LockContract(
msg.sender,
_receiver,
Expand Down Expand Up @@ -226,7 +225,7 @@ contract HashedTimelockERC20 {
)
{
if (haveContract(_contractId) == false)
return;
return (address(0), address(0), address(0), 0, 0, 0, false, false, 0);
LockContract storage c = contracts[_contractId];
return (
c.sender,
Expand Down
2 changes: 1 addition & 1 deletion contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.4.23;
pragma solidity ^0.5.0;

contract Migrations {
address public owner;
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-register": "^6.26.0",
"openzeppelin-solidity": "^1.9.0"
"openzeppelin-solidity": "^2.1.2"
},
"devDependencies": {
"bluebird": "^3.5.1"
Expand Down
12 changes: 6 additions & 6 deletions test/helper/ASEANToken.sol
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
pragma solidity ^0.4.23;
pragma solidity ^0.5.0;

import "openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";

/**
* A basic token for testing the HashedTimelockERC20.
*/
contract ASEANToken is StandardToken {
contract ASEANToken is ERC20 {
string public constant name = "ASEAN Token";
string public constant symbol = "ASEAN";
uint8 public constant decimals = 18;
constructor(uint _initialBalance) public {
balances[msg.sender] = _initialBalance;

constructor(uint256 _initialBalance) public {
_mint(msg.sender, _initialBalance);
}
}
6 changes: 5 additions & 1 deletion test/helper/assert.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
if (!global.assert) global.assert = require('chai').assert

const assertEqualBN = (actual, expected, msg = 'numbers not equal') => {
if (!web3.utils.isBN(actual))
actual = web3.utils.toBN(actual)
if (!web3.utils.isBN(expected))
expected = web3.utils.toBN(expected)
assert.isTrue(
actual.equals(expected),
actual.eq(expected),
`
\tmsg: ${msg}
\tactual: ${actual.toString()}
Expand Down
7 changes: 5 additions & 2 deletions test/helper/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ const newSecretHashPair = () => {

const nowSeconds = () => Math.floor(Date.now() / 1000)

const gasPrice = 100000000000 // truffle fixed gas price
const txGas = txReceipt => txReceipt.receipt.gasUsed * gasPrice
const defaultGasPrice = 100000000000 // truffle fixed gas price
const txGas = (txReceipt, gasPrice = defaultGasPrice) => web3.utils.toBN(txReceipt.receipt.gasUsed * gasPrice)
const txLoggedArgs = txReceipt => txReceipt.logs[0].args
const txContractId = txReceipt => txLoggedArgs(txReceipt).contractId

Expand Down Expand Up @@ -58,8 +58,11 @@ const htlcERC20ArrayToObj = c => {
}
}

const getBalance = async (address) => web3.utils.toBN(await web3.eth.getBalance(address))

export {
bufToStr,
getBalance,
htlcArrayToObj,
htlcERC20ArrayToObj,
isSha256Hash,
Expand Down
41 changes: 22 additions & 19 deletions test/htlc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Promise from 'bluebird'
import {assertEqualBN} from './helper/assert'
import {
bufToStr,
getBalance,
htlcArrayToObj,
isSha256Hash,
newSecretHashPair,
Expand All @@ -15,11 +16,11 @@ import {

const HashedTimelock = artifacts.require('./HashedTimelock.sol')

const REQUIRE_FAILED_MSG = 'VM Exception while processing transaction: revert'
const REQUIRE_FAILED_MSG = 'Returned error: VM Exception while processing transaction: revert'

const hourSeconds = 3600
const timeLock1Hour = nowSeconds() + hourSeconds
const oneFinney = web3.toWei(1, 'finney')
const oneFinney = web3.utils.toWei(web3.utils.toBN(1), 'finney')

contract('HashedTimelock', accounts => {
const sender = accounts[1]
Expand All @@ -44,15 +45,15 @@ contract('HashedTimelock', accounts => {

assert.equal(logArgs.sender, sender)
assert.equal(logArgs.receiver, receiver)
assert.equal(logArgs.amount, oneFinney)
assertEqualBN(logArgs.amount, oneFinney)
assert.equal(logArgs.hashlock, hashPair.hash)
assert.equal(logArgs.timelock, timeLock1Hour)

const contractArr = await htlc.getContract.call(contractId)
const contract = htlcArrayToObj(contractArr)
assert.equal(contract.sender, sender)
assert.equal(contract.receiver, receiver)
assert.equal(contract.amount, oneFinney)
assertEqualBN(contract.amount, oneFinney)
assert.equal(contract.hashlock, hashPair.hash)
assert.equal(contract.timelock.toNumber(), timeLock1Hour)
assert.isFalse(contract.withdrawn)
Expand All @@ -73,7 +74,7 @@ contract('HashedTimelock', accounts => {
})
assert.fail('expected failure due to 0 value transferred')
} catch (err) {
assert.equal(err.message, REQUIRE_FAILED_MSG)
assert.isTrue(err.message.startsWith(REQUIRE_FAILED_MSG))
}
})

Expand All @@ -89,7 +90,7 @@ contract('HashedTimelock', accounts => {

assert.fail('expected failure due past timelock')
} catch (err) {
assert.equal(err.message, REQUIRE_FAILED_MSG)
assert.isTrue(err.message.startsWith(REQUIRE_FAILED_MSG))
}
})

Expand All @@ -109,7 +110,7 @@ contract('HashedTimelock', accounts => {
})
assert.fail('expected failure due to duplicate request')
} catch (err) {
assert.equal(err.message, REQUIRE_FAILED_MSG)
assert.isTrue(err.message.startsWith(REQUIRE_FAILED_MSG))
}
})

Expand All @@ -127,19 +128,20 @@ contract('HashedTimelock', accounts => {
)

const contractId = txContractId(newContractTx)
const receiverBalBefore = web3.eth.getBalance(receiver)
const receiverBalBefore = await getBalance(receiver)

// receiver calls withdraw with the secret to get the funds
const withdrawTx = await htlc.withdraw(contractId, hashPair.secret, {
from: receiver,
})
const tx = await web3.eth.getTransaction(withdrawTx.tx)

// Check contract funds are now at the receiver address
const expectedBal = receiverBalBefore
.plus(oneFinney)
.minus(txGas(withdrawTx))
.add(oneFinney)
.sub(txGas(withdrawTx, tx.gasPrice))
assertEqualBN(
web3.eth.getBalance(receiver),
await getBalance(receiver),
expectedBal,
"receiver balance doesn't match"
)
Expand Down Expand Up @@ -170,7 +172,7 @@ contract('HashedTimelock', accounts => {
await htlc.withdraw(contractId, wrongSecret, {from: receiver})
assert.fail('expected failure due to 0 value transferred')
} catch (err) {
assert.equal(err.message, REQUIRE_FAILED_MSG)
assert.isTrue(err.message.startsWith(REQUIRE_FAILED_MSG))
}
})

Expand All @@ -192,7 +194,7 @@ contract('HashedTimelock', accounts => {
await htlc.withdraw(contractId, hashPair.secret, {from: someGuy})
assert.fail('expected failure due to wrong receiver')
} catch (err) {
assert.equal(err.message, REQUIRE_FAILED_MSG)
assert.isTrue(err.message.startsWith(REQUIRE_FAILED_MSG))
}
})

Expand Down Expand Up @@ -222,7 +224,7 @@ contract('HashedTimelock', accounts => {
new Error('expected failure due to withdraw after timelock expired')
)
} catch (err) {
assert.equal(err.message, REQUIRE_FAILED_MSG)
assert.isTrue(err.message.startsWith(REQUIRE_FAILED_MSG))
resolve()
}
}, 1000)
Expand All @@ -249,12 +251,13 @@ contract('HashedTimelock', accounts => {
return new Promise((resolve, reject) =>
setTimeout(async () => {
try {
const balBefore = web3.eth.getBalance(sender)
const tx = await htlc.refund(contractId, {from: sender})
const balBefore = await getBalance(sender)
const refundTx = await htlc.refund(contractId, {from: sender})
const tx = await web3.eth.getTransaction(refundTx.tx)
// Check contract funds are now at the senders address
const expectedBal = balBefore.plus(oneFinney).minus(txGas(tx))
const expectedBal = balBefore.add(oneFinney).sub(txGas(refundTx, tx.gasPrice))
assertEqualBN(
web3.eth.getBalance(sender),
await getBalance(sender),
expectedBal,
"sender balance doesn't match"
)
Expand Down Expand Up @@ -286,7 +289,7 @@ contract('HashedTimelock', accounts => {
await htlc.refund(contractId, {from: sender})
assert.fail('expected failure due to timelock')
} catch (err) {
assert.equal(err.message, REQUIRE_FAILED_MSG)
assert.isTrue(err.message.startsWith(REQUIRE_FAILED_MSG))
}
})

Expand Down
Loading

0 comments on commit daf3590

Please sign in to comment.