Skip to content
This repository has been archived by the owner on Apr 25, 2023. It is now read-only.

Commit

Permalink
cleanup + refactoring tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Christophe Le Bars committed Jul 24, 2018
1 parent 27b4b87 commit 9e9fecb
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 135 deletions.
2 changes: 1 addition & 1 deletion contracts/EIP20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ contract EIP20 is EIP20Interface {
uint8 public decimals; //How many decimals to show.
string public symbol; //An identifier: eg SBX

function EIP20(
constructor (
uint256 _initialAmount,
string _tokenName,
uint8 _decimalUnits,
Expand Down
6 changes: 3 additions & 3 deletions contracts/Migrations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ contract Migrations {
if (msg.sender == owner) _;
}

function Migrations() {
constructor() public {
owner = msg.sender;
}

function setCompleted(uint completed) restricted {
function setCompleted(uint completed) restricted public {
last_completed_migration = completed;
}

function upgrade(address new_address) restricted {
function upgrade(address new_address) restricted public {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
Expand Down
25 changes: 11 additions & 14 deletions contracts/SimpleRougeCampaign.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ contract SimpleRougeCampaign {
factory = RougeFactoryInterface(_factory);
}

// web3.eth.sign compat prefix XXX mv to lib
function prefixed(bytes32 hash) internal pure returns (bytes32) {
return keccak256("\x19Ethereum Signed Message:\n32", hash);
}

string public name;
bool public campaignIssued;
uint public campaignExpiration;
Expand All @@ -51,7 +56,9 @@ contract SimpleRougeCampaign {
uint256 rgeBalance = rge.balanceOf(this);
require(rgeBalance >= issuance * tare);

// TODO XXX limit expiration to now + 3 months ?
// minimum campaign duration 1 day, maximum 120 days
require(_campaignExpiration >= now + 60*60*24);
require(_campaignExpiration <= now + 60*60*24*120);

name = _name;
campaignIssued = true;
Expand All @@ -66,9 +73,6 @@ contract SimpleRougeCampaign {
_;
}

/* ********** ********** ********** */
/* the acquisition Register (track if an address has a note) XXX to replace by Int ? */

mapping (address => bool) acquisitionRegister;

function hasNote(address _bearer) constant public returns (bool yes) {
Expand Down Expand Up @@ -135,25 +139,18 @@ contract SimpleRougeCampaign {
return true;
}

// web3.eth.sign compat prefix
function prefixed(bytes32 hash) internal pure returns (bytes32) {
return keccak256("\x19Ethereum Signed Message:\n32", hash);
}

// _hash is any hashed msg agreed between issuer and bearer
// WARNING: replay protection not implemented at protocol level
function acceptRedemption(address _bearer, bytes32 _hash, uint8 v, bytes32 r, bytes32 s)
CampaignOpen onlyBy(issuer) public returns (bool success) {

bytes32 message = prefixed(_hash);

require(ecrecover(message, v, r, s) == _bearer);

return redeemNote(_bearer);
}

function confirmRedemption(bytes32 _hashmsg, uint8 v, bytes32 r, bytes32 s) CampaignOpen public returns (bool success) {
require(ecrecover(_hashmsg, v, r, s) == issuer);
function confirmRedemption(bytes32 _hash, uint8 v, bytes32 r, bytes32 s) CampaignOpen public returns (bool success) {
bytes32 message = prefixed(_hash);
require(ecrecover(message, v, r, s) == issuer);
return redeemNote(msg.sender);
}

Expand Down
6 changes: 5 additions & 1 deletion contracts/TestRGEToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ contract TestRGEToken is EIP20 {

/* RGEToken */
address owner;
string public version = 'v0.01';
string public version = 'v0.03';
uint256 public totalSupply = 1000000000 * 10**uint(decimals);
uint256 public reserveY1 = 300000000 * 10**uint(decimals);
uint256 public reserveY2 = 200000000 * 10**uint(decimals);

/* set a maximum per address */
uint256 public maxBalance = 1000000 * 10**uint(decimals);

modifier onlyBy(address _address) {
require(msg.sender == _address);
_;
Expand All @@ -35,6 +38,7 @@ contract TestRGEToken is EIP20 {
}

function giveMeRGE(uint256 _value) public returns (bool success) {
require(balances[msg.sender] + _value <= maxBalance);
require(balances[owner] >= _value);
balances[owner] -= _value;
balances[msg.sender] += _value;
Expand Down
4 changes: 2 additions & 2 deletions migrations/2_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

var TestRGEToken = artifacts.require("./TestRGEToken.sol");
var RougeFactory = artifacts.require("./RougeFactory.sol");
const TestRGEToken = artifacts.require("./TestRGEToken.sol");
const RougeFactory = artifacts.require("./RougeFactory.sol");

module.exports = async function(deployer) {

Expand Down
141 changes: 27 additions & 114 deletions test/RougeFactory.js
Original file line number Diff line number Diff line change
@@ -1,145 +1,58 @@

var RGEToken = artifacts.require("./TestRGEToken.sol");
var Factory = artifacts.require("./RougeFactory.sol");
var SimpleRougeCampaign = artifacts.require("./SimpleRougeCampaign.sol");
const RGEToken = artifacts.require("./TestRGEToken.sol");
const Factory = artifacts.require("./RougeFactory.sol");
const SimpleRougeCampaign = artifacts.require("./SimpleRougeCampaign.sol");

var tare = 0.1 * 10**6; /* price price is 0.1 rge in beta phase */
const tare = 0.1 * 10**6; /* tare price is 0.1 rge in beta phase */

contract('RougeFactory', function(accounts) {

it("factory has correct parameters", async function() {

const rge = await RGEToken.deployed();
const factory = await Factory.deployed();

const ftare = await factory.tare.call();
assert.equal(ftare.toNumber(), tare, "tare price is set correctly in factory");

});

it("create a simple Rouge campaign", async function() {

var issuer = accounts[1];
var tokens = 1000 * 10**6; /* 1K RGE tokens */
const issuer = accounts[1];
const tokens = 1000 * 10**6; /* 1K RGE tokens */

var issuance = 10;
var deposit = 50 * 10**6;
const issuance = 10;
const deposit = 50 * 10**6;

let rge = await RGEToken.deployed();
let factory = await Factory.deployed();
const rge = await RGEToken.deployed();
const factory = await Factory.deployed();

let issuer_balance_before = await rge.balanceOf.call(issuer);
const issuer_balance_before = await rge.balanceOf.call(issuer);
assert.equal(issuer_balance_before.toNumber(), 0, "issuer has no rge tokens to start with");

await rge.giveMeRGE(tokens, {from: issuer});

let issuer_balance_post = await rge.balanceOf.call(issuer);
const issuer_balance_post = await rge.balanceOf.call(issuer);
assert.equal(issuer_balance_post.toNumber(), tokens, "issuer has receive tokens to create a campaign");

await rge.newCampaign(issuance, deposit, {from: issuer, gas: 2000000, gasPrice: web3.toWei(1, "gwei")})

let issuer_balance_after = await rge.balanceOf.call(issuer);
const issuer_balance_after = await rge.balanceOf.call(issuer);
assert.equal(issuer_balance_after.toNumber(), tokens - deposit, "issuer has sent tokens as a deposit to the factory");

let campaign_count = await factory.get_all_count.call();
const campaign_count = await factory.get_all_count.call();
assert.equal(campaign_count.toNumber(), 1, "one campaign has been created");

let campaign_address = await factory.get_campaign.call(issuer, 0);
const campaign_address = await factory.get_campaign.call(issuer, 0);

let factory_balance = await rge.balanceOf.call(factory.address);
const factory_balance = await rge.balanceOf.call(factory.address);
assert.equal(factory_balance.toNumber(), 0, "no tokens deposit in the factory");

let campaign_balance = await rge.balanceOf.call(campaign_address);
const campaign_balance = await rge.balanceOf.call(campaign_address);
assert.equal(campaign_balance.toNumber(), deposit, "the tokens deposit is now in the new campaign contract");

});

it("simple tare burning test with no redemption", async function() {

var issuer = accounts[2];
var tokens = 1000 * 10**6;

var issuance = 10;
var deposit = 50 * 10**6;

let rge = await RGEToken.deployed();
let factory = await Factory.deployed();

await rge.giveMeRGE(tokens, {from: issuer});
await rge.newCampaign(issuance, deposit, {from: issuer, gas: 2000000, gasPrice: web3.toWei(1, "gwei")})
let campaign_address = await factory.get_campaign.call(issuer, 0);

let ftare = await factory.tare.call();
assert.equal(ftare.toNumber(), tare, "tare price is set correctly in factory");

let campaign_balance = await rge.balanceOf.call(campaign_address);
assert.equal(campaign_balance.toNumber(), deposit, "the tokens deposit is now in the new campaign contract");

let campaign = SimpleRougeCampaign.at(campaign_address);

// very long expiration // 19 January, 2038 03:14:07 UT ( 2147483647 )
await campaign.issue('Test Simple 2', 2147483647, {from: issuer});

let available = await campaign.available.call();
assert.equal(available.toNumber(), issuance, "check notes available after issuance");

await campaign.kill({from: issuer});

let burned = tare * issuance;

let campaign_balance_after = await rge.balanceOf.call(campaign_address);
assert.equal(campaign_balance_after.toNumber(), 0, "the campaign has no more rge after kill");

let issuer_balance_after = await rge.balanceOf.call(issuer);
assert.equal(issuer_balance_after.toNumber(), tokens - burned, "the issuer has his tokens back less tare for 10 notes");

});

it("acceptRedemption from issuer", async function() {

var issuer = accounts[3];
var bearer = accounts[4];

var tokens = 1000 * 10**6;
var issuance = 10;
var deposit = 50 * 10**6;

let rge = await RGEToken.deployed();
let factory = await Factory.deployed();

await rge.giveMeRGE(tokens, {from: issuer});
await rge.newCampaign(issuance, deposit, {from: issuer, gas: 2000000, gasPrice: web3.toWei(1, "gwei")})
let campaign_address = await factory.get_campaign.call(issuer, 0);

let campaign_balance = await rge.balanceOf.call(campaign_address);
assert.equal(campaign_balance.toNumber(), deposit, "the tokens deposit is now in the new campaign contract");

let campaign = SimpleRougeCampaign.at(campaign_address);

await campaign.issue('acceptRedemption Test', 2147483647, {from: issuer});
await campaign.giveNote(bearer, {from: issuer});

let acquired = await campaign.acquired.call();
assert.equal(acquired.toNumber(), 1, "check notes acquired after giveNote");

// at minimum, msg needs to include the campaign address to protect against replay
let msg = campaign_address + 'valid ticket';

// bearer signature that to be used by issuer
let signature = web3.eth.sign(bearer, web3.sha3(msg));
signature = signature.substr(2);
const r = '0x' + signature.slice(0, 64)
const s = '0x' + signature.slice(64, 128)
const v = '0x' + signature.slice(128, 130)
const v_decimal = web3.toDecimal(v) + 27

await campaign.acceptRedemption(bearer, web3.sha3(msg), v_decimal, r, s, {from: issuer});

let redeemed = await campaign.redeemed.call();
assert.equal(redeemed.toNumber(), 1, "notes redeemed after confirmRedemption");

await campaign.kill({from: issuer});

let burned = tare * (issuance - 1);

let campaign_balance_after = await rge.balanceOf.call(campaign_address);
assert.equal(campaign_balance_after.toNumber(), 0, "the campaign has no more rge after kill");

let issuer_balance_after = await rge.balanceOf.call(issuer);
assert.equal(issuer_balance_after.toNumber(), tokens - burned, "the issuer has his tokens back less tare for unredeemed notes");

});


});

Loading

0 comments on commit 9e9fecb

Please sign in to comment.