Skip to content

Commit c205974

Browse files
feat: change auction timeouts to block numbers to remove timestamp
dependency issues - The timestamp of the block might be influenced by miners in certain degree - Added minor improvements
1 parent cafb74a commit c205974

11 files changed

+283
-209
lines changed

truffle/contracts/CryptoCarzAuction.sol

+60-60
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
pragma solidity 0.4.24;
2+
3+
import "./CryptoCarzAuction.sol";
4+
5+
contract CryptoCarzAuctionMock is CryptoCarzAuction {
6+
7+
constructor(address _owner, address _manager, address _token)
8+
CryptoCarzAuction(_owner, _manager, _token) public {
9+
10+
SAFETY_TIMEOUT_BLOCKS = 10;
11+
}
12+
}

truffle/contracts/CryptoCarzControl.sol

+1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ contract CryptoCarzControl {
126126
/// @param _newContractAddress The new smart contract version address.
127127
function upgrade(address _newContractAddress) external onlyOwner ifNotPaused {
128128
require(_newContractAddress != address(0));
129+
require(_newContractAddress != address(this));
129130
newContractAddress = _newContractAddress;
130131
emit ContractUpgrade(newContractAddress);
131132
paused = true;

truffle/contracts/CryptoCarzToken.sol

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ contract CryptoCarzToken is ERC721Token, CryptoCarzControl {
3131
event CreateCars(uint256[] tokenIds, uint256 indexed seriesId);
3232
event CreateAuction(address contractAddress);
3333
event SetTreasurer(address indexed previousTreasurer, address indexed newTreasurer);
34+
event SafeTransfersFrom(address indexed from, address indexed to, uint256[] tokenIds);
3435

3536
/// @dev Overrides ERC721Token's `canTransfer` modifier to check if contract is paused.
3637
/// @param _tokenId ID of the token to validate
@@ -117,6 +118,8 @@ contract CryptoCarzToken is ERC721Token, CryptoCarzControl {
117118
for (uint256 i = 0; i < _tokenIds.length; i++) {
118119
safeTransferFrom(_from, _to, _tokenIds[i]);
119120
}
121+
122+
emit SafeTransfersFrom(_from, _to, _tokenIds);
120123
}
121124

122125
/// @dev Factory function that allows the verified creation of CryptoCarzAuction contracts,

truffle/test/CryptoCarzAuction.test.js

+87-86
Large diffs are not rendered by default.

truffle/test/CryptoCarzControl.test.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,15 @@ contract('CryptoCarzControl', function (accounts) {
122122
await checkUnpause(controlContract, unpause);
123123
});
124124

125-
it('owner can pause but cannot unpause', async function () {
125+
it('manager can pause but cannot unpause', async function () {
126126
const pause = await controlContract.pause({ from: manager });
127127
await checkPause(controlContract, pause);
128128
await assertRevert(controlContract.unpause({ from: manager }));
129129
});
130130

131131
it('can only unpause if paused', async function () {
132132
await assertRevert(controlContract.unpause({ from: owner }));
133-
const pause = await controlContract.pause({ from: owner });
133+
const pause = await controlContract.pause({ from: manager });
134134
await checkPause(controlContract, pause);
135135
const unpause = await controlContract.unpause({ from: owner });
136136
await checkUnpause(controlContract, unpause);
@@ -146,6 +146,7 @@ contract('CryptoCarzControl', function (accounts) {
146146
describe('upgrade', async function () {
147147
it('non-owner accounts cannot upgrade', async function () {
148148
await assertRevert(controlContract.upgrade(someoneElse, { from: manager }));
149+
await assertRevert(controlContract.upgrade(someoneElse, { from: someoneElse }));
149150
});
150151

151152
it('cannot upgrade if paused', async function () {

truffle/test/CryptoCarzToken.test.js

+107-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use strict";
22

3+
const BigNumber = web3.BigNumber;
34
const CryptoCarzAuction = artifacts.require('./CryptoCarzAuction.sol');
45
const CryptoCarzToken = artifacts.require("./CryptoCarzToken.sol");
56
import assertRevert from './assertRevert';
@@ -56,6 +57,15 @@ contract('CryptoCarzToken', function (accounts) {
5657
}
5758
}
5859

60+
async function assertedCreateAuction(account) {
61+
const createAuction = await token.createAuction({ from: account });
62+
assert.equal(createAuction.logs[0].event, 'CreateAuction');
63+
const auction = CryptoCarzAuction.at(createAuction.logs[0].args.contractAddress.valueOf());
64+
const initialized = await auction.initialized.call();
65+
assert.isBoolean(initialized);
66+
assert.isFalse(initialized);
67+
}
68+
5969
async function assertedTransferFrom(token, from, to, tokenId, account) {
6070
const fromBalance = (await token.balanceOf(from)).toNumber();
6171
const toBalance = (await token.balanceOf(to)).toNumber();
@@ -80,12 +90,26 @@ contract('CryptoCarzToken', function (accounts) {
8090
const fromBalance = (await token.balanceOf(from)).toNumber();
8191
const toBalance = (await token.balanceOf(to)).toNumber();
8292
await checkTokensOwnedBy(token, tokenIds, from);
83-
await token.safeTransfersFrom(from, to, tokenIds, { from: account });
93+
const safeTransfersFrom = await token.safeTransfersFrom(from, to, tokenIds, { from: account });
94+
const lastIndex = safeTransfersFrom.logs.length - 1;
95+
assert.equal(safeTransfersFrom.logs[lastIndex].event, 'SafeTransfersFrom');
96+
assert.equal(safeTransfersFrom.logs[lastIndex].args.from.valueOf(), from);
97+
assert.equal(safeTransfersFrom.logs[lastIndex].args.to.valueOf(), to);
98+
assert.equal(`${safeTransfersFrom.logs[lastIndex].args.tokenIds.valueOf()}`, `${tokenIds}`);
8499
await checkTokensOwnedBy(token, tokenIds, to);
85100
assert.equal(await token.balanceOf(from), fromBalance - tokenIds.length);
86101
assert.equal(await token.balanceOf(to), toBalance + tokenIds.length);
87102
}
88103

104+
async function assertedUpgrade(token, newTokenAddress, account) {
105+
const upgrade = await token.upgrade(newTokenAddress, { from: account });
106+
assert.equal(await token.newContractAddress.call(), newTokenAddress);
107+
assert.equal(upgrade.logs[0].event, 'ContractUpgrade');
108+
assert.equal(upgrade.logs[0].args.newContractAddress.valueOf(), newTokenAddress);
109+
assert.isTrue(await token.paused.call());
110+
assert.equal(upgrade.logs[1].event, 'Pause');
111+
}
112+
89113
beforeEach(async function () {
90114
token = await CryptoCarzToken.new(owner, manager, treasurer, { from: someoneElse });
91115
const createSeries = await token.createSeries(4, { from: manager });
@@ -157,6 +181,9 @@ contract('CryptoCarzToken', function (accounts) {
157181
const carIds = [0, 1, 2];
158182
const seriesId = 0;
159183
await assertRevert(token.createCars(carIds, seriesId, { from: owner }));
184+
await assertRevert(token.createCars(carIds, seriesId, { from: someoneElse }));
185+
let createCars = await token.createCars(carIds, seriesId, { from: manager });
186+
await checkCreateCars(token, createCars, carIds, seriesId, manager);
160187
});
161188

162189
it('cannot create new cars when paused', async function () {
@@ -177,6 +204,18 @@ contract('CryptoCarzToken', function (accounts) {
177204
await checkCreateCars(token, createCars, carIds, seriesId, manager);
178205
});
179206

207+
it('can add cars to a series',
208+
async function () {
209+
let carIds = [0, 1, 2];
210+
const seriesId = 0;
211+
212+
let createCars = await token.createCars(carIds, seriesId, { from: manager });
213+
await checkCreateCars(token, createCars, carIds, seriesId, manager);
214+
215+
carIds = [3, 4];
216+
await assertRevert(token.createCars(carIds, seriesId, { from: manager }));
217+
});
218+
180219
it('cannot create more cars within a series than the series max number of cars',
181220
async function () {
182221
let carIds = [0, 1, 2];
@@ -202,7 +241,8 @@ contract('CryptoCarzToken', function (accounts) {
202241

203242
describe('series', async function () {
204243
it('create series', async function () {
205-
await assertRevert(token.createSeries(0, { from: manager }));
244+
let createSeries = await token.createSeries(1, { from: manager });
245+
checkCreateSeries(token, createSeries, 1, 1);
206246
});
207247

208248
it('cannot create a series of max 0 tokens', async function () {
@@ -252,16 +292,74 @@ contract('CryptoCarzToken', function (accounts) {
252292

253293
describe('auction', async function () {
254294
it('can create auctions', async function () {
255-
const createAuction = await token.createAuction({ from: manager });
256-
assert.equal(createAuction.logs[0].event, 'CreateAuction');
257-
const auction = CryptoCarzAuction.at(createAuction.logs[0].args.contractAddress.valueOf());
258-
const initialized = await auction.initialized.call();
259-
assert.isBoolean(initialized);
260-
assert.isFalse(initialized);
295+
await assertedCreateAuction(manager);
261296
});
262297
});
263298

264299
describe('upgrade', async function () {
265-
// TODO
300+
let newTokenAddress;
301+
302+
beforeEach(async function () {
303+
newTokenAddress = (await CryptoCarzToken.new(owner, manager, treasurer, { from: someoneElse })).address;
304+
});
305+
306+
it('can upgrade', async function () {
307+
await assertedUpgrade(token, newTokenAddress, owner);
308+
});
309+
310+
it('can only be done by owner', async function () {
311+
await assertRevert(token.upgrade(newTokenAddress, { from: manager }));
312+
await token.upgrade(newTokenAddress, { from: owner });
313+
});
314+
315+
it('cannot upgrade to 0x0', async function () {
316+
await assertRevert(token.upgrade(constants.ZERO_ADDRESS, { from: owner }));
317+
});
318+
319+
it('cannot upgrade to itself', async function () {
320+
await assertRevert(token.upgrade(token.address, { from: owner }));
321+
});
322+
323+
it('can still call view functions', async function () {
324+
const seriesId = 0;
325+
const carIds = [0, 1, 2, 3];
326+
const createCars = await token.createCars(carIds, seriesId, { from: manager });
327+
await checkCreateCars(token, createCars, carIds, seriesId, manager);
328+
await assertedSafeTransfersFrom(token, manager, users[0], [0, 1], manager);
329+
await assertedSafeTransfersFrom(token, manager, users[1], [2, 3], manager);
330+
await token.approve(users[1], 0, { from: users[0] });
331+
await token.approve(users[0], 2, { from: users[1] });
332+
333+
await assertedUpgrade(token, newTokenAddress, owner);
334+
335+
// This should give us enough information to build a newToken.mintFromOldToken(address).
336+
assert.deepEqual(await Promise.all(carIds.map(carId => token.getCarSeries(carId))),
337+
carIds.map(_ => new BigNumber(seriesId)), 'wrong car series');
338+
assert.equal(await token.balanceOf(users[0]), 2, 'wrong token balance');
339+
assert.equal(await token.balanceOf(users[1]), 2, 'wrong token balance');
340+
assert.equal(await token.tokenOfOwnerByIndex(users[0], 0), 0, 'wrong owned token ID');
341+
assert.equal(await token.tokenOfOwnerByIndex(users[0], 1), 1, 'wrong owned token ID');
342+
assert.equal(await token.tokenOfOwnerByIndex(users[1], 0), 2, 'wrong owned token ID');
343+
assert.equal(await token.tokenOfOwnerByIndex(users[1], 1), 3, 'wrong owned token ID');
344+
assert.equal(await token.getApproved(0), users[1], 'wrong approved address');
345+
assert.equal(await token.getApproved(2), users[0], 'wrong approved address');
346+
// For setApprovalForAll(), we would probably just replay all ApprovalForAll events.
347+
});
348+
349+
it('cannot call ifNotPaused functions', async function () {
350+
const seriesId = 0;
351+
const carIds = [0, 1, 2, 3];
352+
const createCars = await token.createCars(carIds, seriesId, { from: manager });
353+
await checkCreateCars(token, createCars, carIds, seriesId, manager);
354+
await assertedSafeTransfersFrom(token, manager, users[0], [0, 1, 2, 3], manager);
355+
await assertedCreateAuction(manager);
356+
357+
token = await CryptoCarzToken.new(owner, manager, treasurer, { from: someoneElse });
358+
await assertedUpgrade(token, newTokenAddress, owner);
359+
await assertRevert(token.createSeries(4, { from: manager }));
360+
await assertRevert(token.createCars(carIds, seriesId, { from: manager }));
361+
await assertRevert(token.safeTransfersFrom(manager, users[0], [0, 1, 2, 3], { from: manager }));
362+
await assertRevert(token.createAuction({ from: manager }));
363+
});
266364
});
267365
});

truffle/test/constants.js

+1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ exports.DAY = 24 * exports.HOUR;
44
exports.WEEK = 7 * exports.DAY;
55
exports.MONTH = 30 * exports.DAY;
66
exports.YEAR = 12 * exports.MONTH;
7+
exports.AVERAGE_BLOCK_TIME = 15;
78
exports.ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';

truffle/test/increaseBlocks.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default function increaseBlocks (blocks) {
2+
for (let i = 0; i < blocks; i++) {
3+
web3.currentProvider.send({
4+
jsonrpc: '2.0',
5+
method: 'evm_mine',
6+
id: Date.now(),
7+
});
8+
}
9+
}

truffle/test/increaseTime.js

-48
This file was deleted.

truffle/test/latestTime.js

-4
This file was deleted.

0 commit comments

Comments
 (0)