OneSwap Series 14 - Tips for Using Truffle

Test exceptions

constPREFIX="Returned error: VM Exception while processing transaction: ";

module.exports.revert=asyncfunction(promise, errMsg) {
leterrType="revert";
try{
awaitpromise;
thrownull;
} catch(error) {
assert(error, "Expected an error but did not get one");
assert(error.message.startsWith(PREFIX+errType), "Expected an error starting with '"+PREFIX+errType+"' but got '"+error.message+"' instead");
assert.include(error.message, errMsg);
}
};
it("locksend should failed if amt is 0", async() =>{
awaitrevert(lock.lockSend(account_two, 0, token.address, unlock_time),
"LockSend: LOCKED_AMOUNT_SHOULD_BE_NONZERO");
});

Skip block time

  • The LockSend contract uses the block time to determine the unlock time of the locked transfer
  • The SupervisedSend contract uses the block time to determine the unlock time of the supervised transfer
  • The OneSwapGov contract uses block time to determine the expiration time of proposal voting and the interval time of text proposals
  • The OneSwapRouter contract uses block time to determine the deadline of a swap or pending orders
modifier ensure(uint deadline) {
// solhint-disable-next-line not-rely-on-time,
require(deadline >= block.timestamp, "OneSwapRouter: EXPIRED");
_;
}
advanceTime=(time) =>{
returnnewPromise((resolve, reject) =>{
web3.currentProvider.send({
jsonrpc: '2.0',
method: 'evm_increaseTime',
params: [time],
id: newDate().getTime()
}, (err, result) =>{
if(err) { returnreject(err) }
returnresolve(result)
})
})
}
...// Other code omitted

module.exports={
advanceTime,
advanceBlock,
advanceTimeAndBlock,
takeSnapshot,
revertToSnapShot
}
contract("OneSwapGov/tally/failed", (accounts) =>{

before(deployGov);
before(async() =>{ snapshotId=(awaittakeSnapshot())['result']; });
after(async() =>{ awaitrevertToSnapShot(snapshotId); });

it('tally failed: STILL_VOTING', async() =>{
awaitones.approve(gov.address, 2000000);
awaitgov.submitFundsProposal(TITLE, DESC, URL, accounts[9], 0, 1000001);
awaitrevert(gov.tally(), "OneSwapGov: STILL_VOTING");
awaitadvanceTime(VOTE_PERIOD-10);
awaitrevert(gov.tally(), "OneSwapGov: STILL_VOTING");
});
it('tally failed: FINISHED', async() =>{
awaitadvanceTime(11);
awaitgov.tally();
awaitrevert(gov.tally(), "OneSwapGov: NO_PROPOSAL");
});

});

Test event release

it('addMarketOrder/sell: event', async() =>{
awaitbtc.transfer(pair.address, 20000000000, {from: boss});
constresult=awaitpair.addMarketOrder(btc.address, taker, 20000000000, {from: taker});
assert.deepEqual(getLog(result, "NewMarketOrder", decodeNewMarketOrderLog), {
isBuy: false,
amount: 20000000000n,
addrLow: BigInt(taker) &0xffffffffffffffffffffffffffffffffffn,
});
});
functiongetLog(result, eventType, decoder) {
constlog=result.logs.find(log=>log.event==eventType);
assert.isNotNull(log, "log not found: "+eventType);
returndecoder(log);
}
functiondecodeNewMarketOrderLog(log) {
constdata=BigInt(log.args.data);
return{
isBuy: (data&0xffn) >0n,
amount: (data>>8n) &0xffffffffffffffffffffffffffffn,
addrLow: data>>120n,
}
}

Test gas consumption

  • Use the estimateGas() function to estimate the gas consumption of contract execution, or
  • Execute the contract normally, and get the real gas consumption through result.receipt.gasUsed
it("insert sell order with 0 deal", async() =>{
awaitbtc.approve(boss, 1000000000, {from: maker});
awaitusd.approve(boss, 1000000000, {from: maker});
awaitbtc.transferFrom(maker, pair.address, 100, {from: boss});
letresult=awaitpair.addLimitOrder(false, maker, 100, makePrice32(10000000, 18), 1, merge3(0, 0, 0), {from: maker})
console.log("gas on first insert: ", result.receipt.gasUsed);
...// Other code omitted
});

Improve test coverage

Summary

Reference

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store