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

Commit

Permalink
initial commit - skeleton coupon
Browse files Browse the repository at this point in the history
  • Loading branch information
vdg committed Jul 30, 2017
0 parents commit 364ba83
Show file tree
Hide file tree
Showing 12 changed files with 1,010 additions and 0 deletions.
661 changes: 661 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# The Rouge Project - experimental code for the demo coupon platform

This repository contains Solidity smart contract code about the coupon platform built by the Rouge Project.

WARNING : this is EXPERIMENTAL and NON AUDITED code. ONLY use for TESTS purpose (on a testnet!)

This version contains very preliminary skeleton for coupons that are managed on the Ethereum blockchain.

The project use the truffle framework (http://truffleframework.com/)

## How to run tests :

### 1. install truffle :

```
npm install -g truffle
```
### 2. start a testnet (e.g. EthereumJS TestRPC: https://github.com/ethereumjs/testrpc)

### 3. launch the tests

```
truffle test
```

That's all for now...

### Licensed under GNU AFFERO GENERAL PUBLIC LICENSE v3

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
9 changes: 9 additions & 0 deletions contracts/Coupon.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Abstract contract for a Coupon

// TODO

pragma solidity ^0.4.12;

contract Coupon {

}
46 changes: 46 additions & 0 deletions contracts/CouponExample.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
The Rouge Project - Blochain Coupon platform
Copyright (C) 2017 Valentin D. Guillois <[email protected]>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***************************************************
WARNING : EXPERIMENTAL and NON AUDITED code.
only use for tests purpose (on a testnet!)
*/

import "./StandardCoupon.sol";

pragma solidity ^0.4.12;

contract CouponExample is StandardCoupon {

string public name;
string public version = 'v0.1';
uint8 public termDiscount;

function CouponExample (
string _name,
uint256 _initialSupply,
uint8 _termDiscount
) {
issuer = msg.sender;
name = _name;
termDiscount = _termDiscount;
totalFree = _initialSupply;
}

}
9 changes: 9 additions & 0 deletions contracts/CouponUserApprovalLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pragma solidity ^0.4.12;

library CouponUserApprovalLib {

function convert(uint amount,uint conversionRate) returns (uint convertedAmount) {
return amount * conversionRate;
}

}
23 changes: 23 additions & 0 deletions contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pragma solidity ^0.4.4;

contract Migrations {
address public owner;
uint public last_completed_migration;

modifier restricted() {
if (msg.sender == owner) _;
}

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

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

function upgrade(address new_address) restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
161 changes: 161 additions & 0 deletions contracts/StandardCoupon.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
The Rouge Project - Blochain Coupon platform
Copyright (C) 2017 Valentin D. Guillois <[email protected]>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***************************************************
WARNING : EXPERIMENTAL and NON AUDITED code.
only use for tests purpose (on a testnet!)
This is main contract that encapsule the coupon workflow logic
User is here wiewed as a single address/account
(A physical person could have more than 1, to be handled by identity control)
*/
pragma solidity ^0.4.12;

import "./Coupon.sol";

contract StandardCoupon is Coupon {

/*
todo ? struct Authority to replace issuer in some meta task ..
*/

enum States { Created, Issued, Expired, Archived }

States public state = States.Created;

modifier atState(States _state) {
require(state == _state);
_;
}

modifier onlyBy(address _account) {
require(msg.sender == _account);
_;
}

/*
Struct Issuer with in $params ?
=> user approval process contract (from library)
=> coupon terms contract (from library?)
=> expiration rules contract ...
issuance is locking RGE futur bying (in eth)
*/

address issuer; /* Issuer has been set up at the contract creation */

/* set up some parameters like expiration at issuance ? */

function issue() atState(States.Created) onlyBy(issuer) {
state = States.Issued;
}

uint256 totalFree;
uint256 totalAcquired = 0;
uint256 totalRedeemed = 0;

/* ********** ********** ********** */
/* the acquisition Register (track coupons effectively distributed to Users) */

mapping (address => bool) acquisitionRegister;

function freeCouponSupply() constant returns (uint256 free) {
return totalFree;
}

function hasCoupon(address _user) constant returns (bool yes) {
require(_user != issuer); /* SI_10 issuer is excluded for now to simplify tests */
return acquisitionRegister[_user];
}

function distributeCoupon(address _to) atState(States.Issued) private returns (bool success) {
require(_to != issuer); /* SI_10 issuer is excluded for now to simplify tests */
require(!hasCoupon(_to));
if (totalFree > 0) {
totalFree -= 1;
totalAcquired += 1;
acquisitionRegister[_to] = true;
return true;
} else {
return false;
}
}

/* low level transfer of coupon between users =/= high level second market */
function transfer(address _from, address _to) atState(States.Issued) private {
require(_to != issuer); /* SI_10 issuer is excluded for now to simplify tests */
require(hasCoupon(_from));
acquisitionRegister[_from] = false; /* SI_11 _from == _to doesn't really matter here ... */
acquisitionRegister[_to] = true;
}

/* ********** ********** ********** */
/* Functions that manage the acquisition process for coupons */

function askForCoupon() atState(States.Issued) returns (bool success) {
require(msg.sender != issuer); /* SI_10 issuer is excluded for now to simplify tests */
require(!hasCoupon(msg.sender)); /* duplicate test. remove ? */

/* TODO send to approval contract => return always ok in these tests */

return distributeCoupon(msg.sender);
}

function giveCoupon(address _to) onlyBy(issuer) atState(States.Issued) returns (bool success) {
return distributeCoupon(_to);
}


/* ********** ********** ********** */
/* the redemtion Register (track coupons effectively redeemed by Users) */

mapping (address => bool) redemptionRegister;

function hasRedeemed(address _user) constant returns (bool yes) {
require(_user != issuer);
return redemptionRegister[_user];
}

function redeemCoupon(address _user) atState(States.Issued) private returns (bool success) {
require(_user != issuer); /* SI_10 issuer is excluded for now to simplify tests */
require(hasCoupon(_user));
require(!hasRedeemed(_user));
totalRedeemed += 1;
redemptionRegister[_user] = true;
return true;
}

function useCoupon() atState(States.Issued) returns (bool success) {
require(msg.sender != issuer); /* SI_10 issuer is excluded for now to simplify tests */

/* TODO global contract expiration test => if expired change state */

/* TODO send to checkout contract => return always ok in these tests (could put conditions on pos/target)
require approval from issuer
*/

return redeemCoupon(msg.sender);
}


/* todo: self destruct fct by issuer if conditions met */


}
5 changes: 5 additions & 0 deletions migrations/1_initial_migration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var Migrations = artifacts.require("./Migrations.sol");

module.exports = function(deployer) {
deployer.deploy(Migrations);
};
7 changes: 7 additions & 0 deletions migrations/2_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
var CouponExample = artifacts.require("./CouponExample.sol");

module.exports = function(deployer) {

deployer.deploy(CouponExample, 'Coupon demo v0.1', 100, 20);

};
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "Rouge-Coupon-Demo",
"version": "0.0.1",
"description": "The Rouge Project coupon platform demo",
"main": "",
"keywords": [
"ethereum", "coupon"
],
"authors": [
"Valentin D. Guillois <[email protected]>"
],
"license": "AGPL",
}
26 changes: 26 additions & 0 deletions test/TestCouponExample.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
pragma solidity ^0.4.2;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/CouponExample.sol";

contract TestCouponExample {

function testInitialFreeSupplyUsingDeployedContract() {
CouponExample coupon = CouponExample(DeployedAddresses.CouponExample());

uint expected = 100;

Assert.equal(coupon.freeCouponSupply(), expected, "Free Coupon supply should be 100 initially");
}

function testInitialFreeSupplyWithNewCouponExample() {

uint expected = 99;

CouponExample coupon = new CouponExample('COUPON test', expected, 10);

Assert.equal(coupon.freeCouponSupply(), expected, "Owner should have 99 CouponExample initially");
}

}
9 changes: 9 additions & 0 deletions truffle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*" // Match any network id
}
}
};

0 comments on commit 364ba83

Please sign in to comment.