Skip to content

Instantly share code, notes, and snippets.

@jcb82
Created November 21, 2018 21:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcb82/b5991669c7d46e74e2a7cf11c8346dd8 to your computer and use it in GitHub Desktop.
Save jcb82/b5991669c7d46e74e2a7cf11c8346dd8 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.25+commit.59dbf8f1.js&optimize=false&gist=
pragma solidity ^0.4.18;
import "./TestFramework.sol";
import "./Bidders.sol";
contract SimpleAuction is Auction {
// constructor
constructor(address _sellerAddress,
address _judgeAddress,
address _timerAddress,
address _winner,
uint _winningPrice) public payable
Auction (_sellerAddress, _judgeAddress, _timerAddress) {
if (_winner != 0)
declareWinner(_winner, _winningPrice);
}
function declareWinner(address _winner, uint _winningPrice) public {
winnerAddress = _winner;
winningPrice = _winningPrice;
}
//can receive money
function() public payable {}
}
contract ArbitrationTest {
SimpleAuction testAuction;
// Adjust this to change the test code's initial balance
uint public initialBalance = 1000000000 wei;
Participant judge;
Participant seller;
Participant winner;
Participant other;
//can receive money
function() public payable {}
constructor() public payable {}
function setupContracts(bool winnerDeclared, bool hasJudge) public {
judge = new Participant(Auction(0));
winner = new Participant(Auction(0));
seller = new Participant(Auction(0));
other = new Participant(Auction(0));
if (hasJudge)
testAuction = new SimpleAuction(seller, judge, 0, 0, 100);
else
testAuction = new SimpleAuction(seller, 0, 0, 0, 100);
address(testAuction).transfer(100 wei);
if (winnerDeclared)
testAuction.declareWinner(winner, 100);
judge.setAuction(testAuction);
seller.setAuction(testAuction);
winner.setAuction(testAuction);
other.setAuction(testAuction);
}
function testCreateContracts() public {
setupContracts(false, true);
Assert.isFalse(false, "this test should not fail");
Assert.isTrue(true, "this test should never fail");
Assert.equal(uint(7), uint(7), "this test should never fail");
}
function testEarlyFinalize() public {
setupContracts(false, true);
Assert.isFalse(judge.callFinalize(), "finalize with no declared winner should be rejected");
}
function testEarlyRefund() public {
setupContracts(false, true);
Assert.isFalse(judge.callRefund(), "refund with no declared winner should be rejected");
}
function testUnauthorizedRefund() public {
setupContracts(true, true);
Assert.isFalse(winner.callRefund(), "unauthorized refund call should be rejected");
Assert.isFalse(other.callRefund(), "unauthorized refund call should be rejected");
setupContracts(true, false);
Assert.isFalse(judge.callRefund(), "unauthorized refund call should be rejected");
}
function testUnauthorizedFinalize() public {
setupContracts(true, true);
Assert.isFalse(seller.callFinalize(), "unauthorized finalize call should be rejected");
Assert.isFalse(other.callFinalize(), "unauthorized finalize call should be rejected");
}
function testJudgeFinalize() public {
setupContracts(true, true);
Assert.isTrue(judge.callFinalize(), "judge finalize call should succeed");
Assert.isTrue(seller.callWithdraw(), "seller withdraw call should succeed");
Assert.equal(address(seller).balance, 100, "seller should receive funds after finalize");
}
function testWinnerFinalize() public {
setupContracts(true, true);
Assert.isTrue(winner.callFinalize(), "winner finalize call should succeed");
Assert.isTrue(seller.callWithdraw(), "seller withdraw call should succeed");
Assert.equal(address(seller).balance, 100, "seller should receive funds after finalize");
}
function testPublicFinalize() public {
setupContracts(true, false);
Assert.isTrue(other.callFinalize(), "public finalize call should succeed");
Assert.isTrue(seller.callWithdraw(), "seller withdraw call should succeed");
Assert.equal(address(seller).balance, 100, "seller should receive funds after finalize");
}
function testJudgeRefund() public {
setupContracts(true, true);
Assert.isTrue(judge.callRefund(), "judge refund call should succeed");
Assert.isTrue(winner.callWithdraw(), "seller withdraw call should succeed");
Assert.equal(address(winner).balance, 100, "winner should receive funds after refund");
}
function testSellerRefund() public {
setupContracts(true, false);
Assert.isTrue(seller.callRefund(), "seller refund call should succeed");
Assert.isTrue(winner.callWithdraw(), "seller withdraw call should succeed");
Assert.equal(address(winner).balance, 100, "winner should receive funds after refund");
}
}
pragma solidity ^0.4.18;
import "./Timer.sol";
contract Auction {
address internal judgeAddress;
address internal timerAddress;
address internal sellerAddress;
address internal winnerAddress;
uint winningPrice;
// TODO: place your code here
// constructor
constructor(address _sellerAddress,
address _judgeAddress,
address _timerAddress) public {
judgeAddress = _judgeAddress;
timerAddress = _timerAddress;
sellerAddress = _sellerAddress;
if (sellerAddress == 0)
sellerAddress = msg.sender;
}
// This is provided for testing
// You should use this instead of block.number directly
// You should not modify this function.
function time() public view returns (uint) {
if (timerAddress != 0)
return Timer(timerAddress).getTime();
return block.number;
}
function getWinner() public view returns (address winner) {
return winnerAddress;
}
function getWinningPrice() public view returns (uint price) {
return winningPrice;
}
// If no judge is specified, anybody can call this.
// If a judge is specified, then only the judge or winning bidder may call.
function finalize() public {
// TODO: place your code here
}
// This can ONLY be called by seller or the judge (if a judge exists).
// Money should only be refunded to the winner.
function refund() public {
// TODO: place your code here
}
// Withdraw funds from the contract.
// If called, all funds available to the caller should be refunded.
// This should be the *only* place the contract ever transfers funds out.
// Ensure that your withdrawal functionality is not vulnerable to
// re-entrancy or unchecked-spend vulnerabilities.
function withdraw() public {
//TODO: place your code here
}
}
pragma solidity ^0.4.18;
import "./TestFramework.sol";
contract Bidders {}
contract Participant {
Auction auction;
constructor(Auction _auction) public {
setAuction(_auction);
}
function setAuction(Auction _auction) public {
auction = _auction;
}
//wrapped call
function callFinalize() public returns (bool success) {
success = address(auction).call.gas(200000)(bytes4 (keccak256("finalize()")));
}
//wrapped call
function callRefund() public returns (bool success) {
success = address(auction).call.gas(200000)(bytes4 (keccak256("refund()")));
}
//wrapped call
function callWithdraw() public returns (bool success) {
success = address(auction).call.gas(200000)(bytes4 (keccak256("withdraw()")));
}
//can receive money
function() public payable {}
}
contract DutchAuctionBidder {
DutchAuction auction;
constructor(DutchAuction _auction) public {
auction = _auction;
}
//wrapped call
function bid(uint bidValue) public returns (bool success){
success = address(auction).call.value(bidValue).gas(200000)(bytes4 (keccak256("bid()")));
}
//wrapped call
function callWithdraw() public returns (bool success) {
success = address(auction).call.gas(200000)(bytes4 (keccak256("withdraw()")));
}
//can receive money
function() public payable{}
}
contract EnglishAuctionBidder {
EnglishAuction auction;
constructor(EnglishAuction _auction) public {
auction = _auction;
}
//wrapped call
function bid(uint bidValue) public returns (bool success){
success = address(auction).call.value(bidValue).gas(200000)(bytes4 (keccak256("bid()")));
}
//wrapped call
function callWithdraw() public returns (bool success) {
success = address(auction).call.gas(200000)(bytes4 (keccak256("withdraw()")));
}
//can receive money
function() public payable{}
}
contract VickreyAuctionBidder {
VickreyAuction auction;
bytes32 nonce;
constructor(VickreyAuction _auction, bytes32 _nonce) public {
auction = _auction;
nonce = _nonce;
}
function setNonce(bytes32 _newNonce) public {
nonce = _newNonce;
}
//wrapped call
function commitBid(uint _bidValue) public returns (bool success) {
success = commitBid(_bidValue, auction.bidDepositAmount());
}
//wrapped call
function commitBid(uint _bidValue, uint _depositValue) public returns (bool success) {
bytes32 commitment = keccak256(abi.encodePacked(_bidValue, nonce));
success = address(auction).call.value(_depositValue).gas(200000)(bytes4 (keccak256("commitBid(bytes32)")), commitment);
}
//wrapped call
function revealBid(uint _bidValue) public returns (bool success) {
success = address(auction).call.value(_bidValue).gas(200000)(bytes4 (keccak256("revealBid(bytes32)")), nonce);
}
//wrapped call
function callWithdraw() public returns (bool success) {
success = address(auction).call.gas(200000)(bytes4 (keccak256("withdraw()")));
}
//can receive money
function() public payable{}
}
pragma solidity ^0.4.18;
import "./Auction.sol";
contract DutchAuction is Auction {
uint public initialPrice;
uint public biddingPeriod;
uint public offerPriceDecrement;
// TODO: place your code here
// constructor
constructor(address _sellerAddress,
address _judgeAddress,
address _timerAddress,
uint _initialPrice,
uint _biddingPeriod,
uint _offerPriceDecrement) public
Auction (_sellerAddress, _judgeAddress, _timerAddress) {
initialPrice = _initialPrice;
biddingPeriod = _biddingPeriod;
offerPriceDecrement = _offerPriceDecrement;
// TODO: place your code here
}
function bid() public payable{
// TODO: place your code here
}
}
pragma solidity ^0.4.18;
import "./TestFramework.sol";
import "./Bidders.sol";
contract DutchAuctionTest {
DutchAuction testAuction;
Timer t;
// Adjust this to change the test code's initial balance
uint public initialBalance = 1000000000 wei;
//can receive money
function() public payable {}
constructor() public payable {}
function setupContracts() public {
t = new Timer(0);
testAuction = new DutchAuction(this, 0, t, 300, 10, 20);
}
function makeBid(uint bidValue,
uint bidTime,
uint expectedPrice,
bool expectedResult,
string message) internal {
DutchAuctionBidder bidder = new DutchAuctionBidder(testAuction);
address(bidder).transfer(bidValue);
uint oldTime = t.getTime();
t.setTime(bidTime);
uint initialAuctionBalance = address(testAuction).balance;
address currentWinner = testAuction.getWinner();
bool result = bidder.bid(bidValue);
if (expectedResult == false) {
Assert.isFalse(result, message);
Assert.equal(currentWinner, testAuction.getWinner(), "no winner should be declared after invalid bid");
}
else{
Assert.isTrue(result, message);
Assert.equal(address(testAuction).balance, initialAuctionBalance + expectedPrice, "auction should retain final price");
Assert.equal(address(bidder).balance, bidValue - expectedPrice, "bidder should be refunded excess bid amount");
Assert.equal(testAuction.getWinner(), bidder, "bidder should be declared the winner");
}
t.setTime(oldTime);
}
function testCreateDutchAuction() public {
setupContracts();
//do nothing, just verify that the constructor actually ran
}
function testLowBids() public {
setupContracts();
makeBid(299, 0, 0, false, "low bid should be rejected");
makeBid(240, 2, 0, false, "low bid should be rejected");
makeBid(100, 5, 0, false, "low bid should be rejected");
}
function testExactBid() public {
setupContracts();
makeBid(300, 0, 300, true, "exact bid should be accepted");
setupContracts();
makeBid(280, 1, 280, true, "exact bid should be accepted");
setupContracts();
makeBid(120, 9, 120, true, "exact bid should be accepted");
}
function testValidBidAfterInvalid() public {
setupContracts();
makeBid(299, 0, 0, false, "low bid should be rejected");
makeBid(300, 0, 300, true, "valid bid after failed bid should succeed");
}
function testLateBid() public {
setupContracts();
makeBid(300, 10, 0, false, "late bid should be rejected");
}
function testSecondValidBid() public {
setupContracts();
makeBid(280, 1, 280, true, "exact bid should be accepted");
makeBid(300, 0, 0, false, "second bid should be rejected");
}
function testRefundHighBid() public {
setupContracts();
makeBid(300, 2, 260, true, "high bid should be accepted");
}
}
pragma solidity ^0.4.18;
import "./Auction.sol";
contract EnglishAuction is Auction {
uint public initialPrice;
uint public biddingPeriod;
uint public minimumPriceIncrement;
// TODO: place your code here
// constructor
constructor(address _sellerAddress,
address _judgeAddress,
address _timerAddress,
uint _initialPrice,
uint _biddingPeriod,
uint _minimumPriceIncrement) public
Auction (_sellerAddress, _judgeAddress, _timerAddress) {
initialPrice = _initialPrice;
biddingPeriod = _biddingPeriod;
minimumPriceIncrement = _minimumPriceIncrement;
// TODO: place your code here
}
function bid() public payable{
// TODO: place your code here
}
// Need to override the default implementation
function getWinner() public view returns (address winner){
return winner;
// TODO: place your code here
}
}
pragma solidity ^0.4.18;
import "./TestFramework.sol";
import "./Bidders.sol";
contract EnglishAuctionTest {
EnglishAuction testAuction;
EnglishAuctionBidder alice;
EnglishAuctionBidder bob;
EnglishAuctionBidder carol;
Timer t;
// Adjust this to change the test code's initial balance
uint public initialBalance = 1000000000 wei;
//can receive money
function() public payable {}
constructor() public payable {}
function setupContracts() public {
t = new Timer(0);
testAuction = new EnglishAuction(this, 0, t, 300, 10, 20);
alice = new EnglishAuctionBidder(testAuction);
bob = new EnglishAuctionBidder(testAuction);
carol = new EnglishAuctionBidder(testAuction);
}
function makeBid(EnglishAuctionBidder bidder,
uint bidValue,
uint bidTime,
bool expectedResult,
string message) internal {
uint oldTime = t.getTime();
uint oldBalance = address(testAuction).balance;
t.setTime(bidTime);
address(bidder).transfer(bidValue);
bool result = bidder.bid(bidValue);
if (expectedResult == false) {
Assert.isFalse(result, message);
}
else {
Assert.isTrue(result, message);
Assert.equal(address(testAuction).balance - oldBalance, bidValue, "auction should retain bid amount");
}
t.setTime(oldTime);
}
function testCreateEnglishAuction() public {
setupContracts();
//do nothing, just verify that the constructor actually ran
}
function testLowInitialBids() public {
setupContracts();
makeBid(alice, 0, 0, false, "low bid should be rejected");
makeBid(alice, 299, 9, false, "low bid should be rejected");
}
function testSingleValidBid() public {
setupContracts();
makeBid(alice, 300, 0, true, "valid bid should be accepted");
t.setTime(10);
Assert.equal(testAuction.getWinner(), address(alice), "single bidder should be declared the winner");
}
function testEarlyWinner() public {
setupContracts();
makeBid(alice, 300, 0, true, "valid bid should be accepted");
t.setTime(9);
Assert.equal(testAuction.getWinner(), 0, "no bidder should be declared before deadline");
}
function testLowFollowupBids() public {
setupContracts();
makeBid(alice, 300, 0, true, "valid bid should be accepted");
makeBid(bob, 319, 9, false, "low bid should be rejected");
makeBid(bob, 250, 7, false, "low bid should be rejected");
}
function testRefundAfterOutbid() public {
setupContracts();
makeBid(alice, 300, 0, true, "valid bid should be accepted");
makeBid(bob, 320, 8, true, "valid bid should be accepted");
Assert.equal(address(bob).balance, 0, "bidder should not retain funds");
Assert.equal(address(testAuction).balance, 620, "auction should retain bidders' funds in escrow");
Assert.equal(address(alice).balance, 0, "outbid bidder should not receive early refund");
alice.callWithdraw();
Assert.equal(address(alice).balance, 300, "outbid bidder should be able to withdraw refund");
}
function testLateBids() public {
setupContracts();
makeBid(alice, 300, 0, true, "valid bid should be accepted");
makeBid(bob, 320, 10, false, "late bid should be rejected");
makeBid(carol, 500, 12, false, "late bid should be rejected");
}
function testIncreaseBid() public {
setupContracts();
makeBid(alice, 300, 0, true, "valid bid should be accepted");
makeBid(alice, 350, 5, true, "second valid bid should be accepted");
t.setTime(14);
Assert.equal(testAuction.getWinner(), 0, "no bidder should be declared before deadline");
t.setTime(15);
Assert.equal(testAuction.getWinner(), address(alice), "repeat bidder should be declared the winner");
Assert.equal(address(alice).balance, 0, "bidder should not retain funds");
Assert.equal(address(testAuction).balance, 650, "auction should retain bidder's funds in escrow");
alice.callWithdraw();
Assert.equal(address(alice).balance, 300, "outbid bidder should be able to withdraw funds");
Assert.equal(address(testAuction).balance, 350, "auction should retain bidder's funds in escrow");
}
function testExtendedBidding() public {
setupContracts();
makeBid(alice, 300, 0, true, "valid bid should be accepted");
makeBid(bob, 310, 4, false, "invalid bid should be rejected");
makeBid(carol, 400, 8, true, "valid bid should be accepted");
makeBid(bob, 450, 12, true, "valid bid should be accepted");
makeBid(alice, 650, 15, true, "valid bid should be accepted");
makeBid(bob, 660, 16, false, "invalid bid should be rejected");
makeBid(alice, 750, 20, true, "valid bid should be accepted");
makeBid(carol, 1337, 29, true, "valid bid should be accepted");
t.setTime(38);
Assert.equal(testAuction.getWinner(), 0, "no bidder should be declared before deadline");
t.setTime(39);
Assert.equal(testAuction.getWinner(), address(carol), "final bidder should be declared the winner");
Assert.equal(address(alice).balance, 0, "bidders should not retain funds");
Assert.equal(address(bob).balance, 970, "bidders should not retain funds");
Assert.equal(address(carol).balance, 0, "bidders should not retain funds");
alice.callWithdraw();
bob.callWithdraw();
carol.callWithdraw();
Assert.equal(address(carol).balance, 400, "bidders should get valid refunds");
Assert.equal(address(bob).balance, 1420, "bidders should get valid refunds");
Assert.equal(address(alice).balance, 1700, "bidders should get valid refunds");
Assert.equal(address(testAuction).balance, 1337, "auction should retain bidder's funds in escrow");
}
}
pragma solidity ^0.4.18;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
constructor() public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
pragma solidity ^0.4.18;
import "./Timer.sol";
import "./Auction.sol";
import "./DutchAuction.sol";
import "./EnglishAuction.sol";
import "./VickreyAuction.sol";
library Assert {
function isFalse(bool value, string message) public pure {
message = message;
if (value)
revert();
}
function isTrue(bool value, string message) public pure {
message = message;
if (!value)
revert();
}
function equal(uint value1, uint value2, string message) public pure {
message = message;
if (value1 != value2)
revert();
}
function equal(bytes32 value1, bytes32 value2, string message) public pure {
message = message;
if (value1 != value2)
revert();
}
function equal(address value1, address value2, string message) public pure {
message = message;
if (value1 != value2)
revert();
}
}
pragma solidity ^0.4.18;
// Simple contract to store time. You should not need to be modify this contract.
contract Timer {
uint time;
uint startTime;
address owner;
// constructor
constructor(uint _startTime) public {
owner = msg.sender;
time = _startTime;
startTime = _startTime;
}
function getTime() public view returns (uint) {
return time;
}
function resetTime() public ownerOnly {
time = startTime;
}
function setTime(uint _newTime) public ownerOnly {
time = _newTime;
}
function offsetTime(uint _offset) public ownerOnly {
time += _offset;
}
modifier ownerOnly {
if (msg.sender != owner)
revert();
_;
}
}
pragma solidity ^0.4.18;
import "./Auction.sol";
contract VickreyAuction is Auction {
uint public minimumPrice;
uint public biddingDeadline;
uint public revealDeadline;
uint public bidDepositAmount;
// TODO: place your code here
// constructor
constructor(address _sellerAddress,
address _judgeAddress,
address _timerAddress,
uint _minimumPrice,
uint _biddingPeriod,
uint _revealPeriod,
uint _bidDepositAmount) public
Auction (_sellerAddress, _judgeAddress, _timerAddress) {
minimumPrice = _minimumPrice;
bidDepositAmount = _bidDepositAmount;
biddingDeadline = time() + _biddingPeriod;
revealDeadline = time() + _biddingPeriod + _revealPeriod;
// TODO: place your code here
}
// Record the player's bid commitment
// Make sure exactly bidDepositAmount is provided (for new bids)
// Bidders can update their previous bid for free if desired.
// Only allow commitments before biddingDeadline
function commitBid(bytes32 bidCommitment) public payable {
// NOOP to silence compiler warning. Delete me.
bidCommitment ^= 0;
// TODO: place your code here
}
// Check that the bid (msg.value) matches the commitment.
// If the bid is correctly opened, the bidder can withdraw their deposit.
function revealBid(bytes32 nonce) public payable returns(bool isHighestBidder) {
// NOOPs to silence compiler warning. Delete me.
nonce ^= 0;
isHighestBidder = false;
// TODO: place your code here
}
// Need to override the default implementation
function getWinner() public view returns (address winner){
// TODO: place your code here
return winner;
}
// finalize() must be extended here to provide a refund to the winner
// based on the final sale price (the second highest bid, or reserve price).
function finalize() public {
// TODO: place your code here
// call the general finalize() logic
super.finalize();
}
}
pragma solidity ^0.4.18;
import "./TestFramework.sol";
import "./Bidders.sol";
contract VickreyAuctionTestAdvanced {
VickreyAuction testAuction;
VickreyAuctionBidder alice;
VickreyAuctionBidder bob;
VickreyAuctionBidder carol;
uint bidderCounter;
Timer t;
// Adjust this to change the test code's initial balance
uint public initialBalance = 1000000000 wei;
//can receive money
function() public payable {}
constructor() public payable {}
function setupContracts() public {
t = new Timer(0);
testAuction = new VickreyAuction(this, 0, t, 300, 10, 10, 1000);
bidderCounter += 1;
alice = new VickreyAuctionBidder(testAuction, bytes32(bidderCounter));
bob = new VickreyAuctionBidder(testAuction, bytes32(bidderCounter));
carol = new VickreyAuctionBidder(testAuction, bytes32(bidderCounter));
}
function commitBid(VickreyAuctionBidder bidder,
uint bidValue,
uint bidTime,
bool expectedResult,
string message) internal {
uint oldTime = t.getTime();
t.setTime(bidTime);
uint initialAuctionBalance = address(testAuction).balance;
address(bidder).transfer(testAuction.bidDepositAmount());
bool result = bidder.commitBid(bidValue);
if (expectedResult == false) {
Assert.isFalse(result, message);
}
else {
Assert.isTrue(result, message);
Assert.equal(address(testAuction).balance, initialAuctionBalance + testAuction.bidDepositAmount(), "auction should retain deposit");
}
t.setTime(oldTime);
}
function revealBid(VickreyAuctionBidder bidder,
uint bidValue,
uint bidTime,
bool expectedResult,
string message) internal {
uint oldTime = t.getTime();
t.setTime(bidTime);
address(bidder).transfer(bidValue);
bool result = bidder.revealBid(bidValue);
if (expectedResult == false) {
Assert.isFalse(result, message);
}
else {
Assert.isTrue(result, message);
}
t.setTime(oldTime);
}
function testMinimalBidder() public {
setupContracts();
commitBid(bob, 300, 9, true, "valid bid commitment should be accepted");
revealBid(bob, 300, 19, true, "valid bid reveal should be accepted");
t.setTime(20);
Assert.equal(address(bob), testAuction.getWinner(), "winner should be declared after auction end");
testAuction.finalize();
Assert.equal(address(bob).balance, 0, "winner should not receive early refund");
bob.callWithdraw();
Assert.equal(address(bob).balance, 1000, "winner should received partial refund");
}
function testRevealChangedBid() public {
setupContracts();
address(alice).transfer(2548);
Assert.isTrue(alice.commitBid(500, 1000), "valid bid should be accepted");
t.setTime(1);
Assert.isTrue(alice.commitBid(550, 0), "valid bid change should be accepted");
revealBid(alice, 500, 14, false, "incorrect bid reveal should be rejected");
revealBid(alice, 550, 14, true, "correct bid reveal should be accepted");
t.setTime(20);
Assert.equal(address(alice), testAuction.getWinner(), "winner should be declared after auction end");
testAuction.finalize();
Assert.equal(address(alice).balance, 2048, "winner should not receive early refund");
alice.callWithdraw();
Assert.equal(address(alice).balance, 3298, "winner should received partial refund");
}
function testMultipleBiddersOne() public {
setupContracts();
commitBid(alice, 500, 1, true, "correct bid should be accepted");
commitBid(bob, 617, 2, true, "correct bid should be accepted");
commitBid(carol, 650, 3, true, "correct bid should be accepted");
revealBid(alice, 500, 14, true, "correct bid reveal should be accepted");
revealBid(bob, 617, 15, true, "correct bid reveal should be accepted");
revealBid(carol, 650, 16, true, "correct bid reveal should be accepted");
t.setTime(20);
Assert.equal(address(carol), testAuction.getWinner(), "winner should be declared after auction end");
testAuction.finalize();
alice.callWithdraw();
bob.callWithdraw();
carol.callWithdraw();
Assert.equal(address(alice).balance, 1500, "loser should received full refund");
Assert.equal(address(bob).balance, 1617, "loser should received full refund");
Assert.equal(address(carol).balance, 1033, "winner should received partial refund");
}
function testMultipleBiddersTwo() public {
setupContracts();
commitBid(alice, 500, 1, true, "correct bid should be accepted");
commitBid(bob, 617, 2, true, "correct bid should be accepted");
commitBid(carol, 650, 3, true, "correct bid reveal should be accepted");
revealBid(carol, 650, 14, true, "correct bid reveal should be accepted");
revealBid(alice, 500, 15, true, "correct bid reveal should be accepted");
revealBid(bob, 617, 16, true, "correct bid reveal should be accepted");
t.setTime(20);
Assert.equal(address(carol), testAuction.getWinner(), "winner should be declared after auction end");
testAuction.finalize();
alice.callWithdraw();
bob.callWithdraw();
carol.callWithdraw();
Assert.equal(address(alice).balance, 1500, "loser should received full refund");
Assert.equal(address(bob).balance, 1617, "loser should received full refund");
Assert.equal(address(carol).balance, 1033, "winner should received partial refund");
}
}
pragma solidity ^0.4.18;
import "./TestFramework.sol";
import "./Bidders.sol";
contract VickreyAuctionTestBasic {
VickreyAuction testAuction;
VickreyAuctionBidder alice;
VickreyAuctionBidder bob;
VickreyAuctionBidder carol;
uint bidderCounter;
Timer t;
// Adjust this to change the test code's initial balance
uint public initialBalance = 1000000000 wei;
//can receive money
function() public payable {}
constructor() public payable {}
function setupContracts() public {
t = new Timer(0);
testAuction = new VickreyAuction(this, 0, t, 300, 10, 10, 1000);
bidderCounter += 1;
alice = new VickreyAuctionBidder(testAuction, bytes32(bidderCounter));
bob = new VickreyAuctionBidder(testAuction, bytes32(bidderCounter));
carol = new VickreyAuctionBidder(testAuction, bytes32(bidderCounter));
}
function commitBid(VickreyAuctionBidder bidder,
uint bidValue,
uint bidTime,
bool expectedResult,
string message) internal {
uint oldTime = t.getTime();
t.setTime(bidTime);
uint initialAuctionBalance = address(testAuction).balance;
address(bidder).transfer(testAuction.bidDepositAmount());
bool result = bidder.commitBid(bidValue);
if (expectedResult == false) {
Assert.isFalse(result, message);
}
else {
Assert.isTrue(result, message);
Assert.equal(address(testAuction).balance, initialAuctionBalance + testAuction.bidDepositAmount(), "auction should retain deposit");
}
t.setTime(oldTime);
}
function revealBid(VickreyAuctionBidder bidder,
uint bidValue,
uint bidTime,
bool expectedResult,
string message) internal {
uint oldTime = t.getTime();
t.setTime(bidTime);
address(bidder).transfer(bidValue);
bool result = bidder.revealBid(bidValue);
if (expectedResult == false) {
Assert.isFalse(result, message);
}
else {
Assert.isTrue(result, message);
}
t.setTime(oldTime);
}
function testCreateVickreyAuction() public {
setupContracts();
//do nothing, just verify that the constructor actually ran
}
function testCommitBids() public {
setupContracts();
commitBid(alice, 10, 1, true, "valid bid commitment should be accepted");
commitBid(bob, 1000, 2, true, "valid bid commitment should be accepted");
commitBid(carol, 340, 7, true, "valid bid commitment should be accepted");
}
function testLateBidCommitments() public {
setupContracts();
commitBid(carol, 340, 7, true, "valid bid commitment should be accepted");
commitBid(alice, 300, 10, false, "late bid commitment should be rejected");
commitBid(bob, 3000, 100, false, "late bid commitment should be rejected");
}
function testExcessBidDeposit() public {
setupContracts();
address(alice).transfer(1067);
Assert.isFalse(alice.commitBid(1000, 1067), "bid with excess deposit should be rejected");
Assert.equal(address(alice).balance, 1067, "bid with excess deposit should be rejected");
}
function testChangeBidCommitmentRefund() public {
setupContracts();
address(alice).transfer(2548);
Assert.isTrue(alice.commitBid(500, 1000), "valid bid should be accepted");
t.setTime(1);
Assert.isTrue(alice.commitBid(550, 0), "valid bid change #1 should be accepted");
t.setTime(2);
Assert.isTrue(alice.commitBid(450, 0), "valid bid change #2 should be accepted");
t.setTime(3);
Assert.isFalse(alice.commitBid(300, 1000), "invalid bid #3 change should be rejected");
Assert.equal(address(testAuction).balance, 1000, "bid changes should still capture deposit");
Assert.equal(address(alice).balance, 1548, "bid changes should not capture additional deposit");
}
function testEarlyReveal() public {
setupContracts();
commitBid(alice, 340, 7, true, "valid bid commitment should be accepted");
revealBid(alice, 340, 9, false, "early bid reveal should be rejected");
}
function testLateReveal() public {
setupContracts();
commitBid(alice, 340, 7, true, "valid bid commitment should be accepted");
revealBid(alice, 340, 20, false, "early bid reveal should be rejected");
}
function testInvalidReveal() public {
setupContracts();
commitBid(alice, 340, 7, true, "valid bid commitment should be accepted");
commitBid(bob, 380, 8, true, "valid bid commitment should be accepted");
revealBid(alice, 320, 14, false, "incorrect bid reveal should be rejected");
bob.setNonce(1);
revealBid(bob, 380, 16, false, "incorrect bid reveal should be rejected");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment