Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
O
openzeppelin-contracts-upgradeable
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
俞永鹏
openzeppelin-contracts-upgradeable
Commits
8d9e12ed
Commit
8d9e12ed
authored
Feb 09, 2017
by
Jorge Izquierdo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add GrantableToken tests
parent
fb0a9633
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
119 additions
and
94 deletions
+119
-94
GrantableTokenMock.sol
contracts/test-helpers/GrantableTokenMock.sol
+8
-4
GrantableToken.sol
contracts/token/GrantableToken.sol
+24
-24
package.json
package.json
+1
-0
AGrantableToken.js
test/AGrantableToken.js
+0
-66
GrantableToken.js
test/GrantableToken.js
+81
-0
timer.js
test/helpers/timer.js
+5
-0
No files found.
contracts/test-helpers/GrantableTokenMock.sol
View file @
8d9e12ed
pragma solidity ^0.4.4;
import "./StandardTokenMock.sol";
contract GrantableTokenMock is StandardTokenMock {
function GrantableTokenMock(address initialAccount, uint initialBalance)
StandardTokenMock(initialAccount, initialBalance) {}
import '../token/GrantableToken.sol';
// mock class using StandardToken
contract GrantableTokenMock is GrantableToken {
function GrantableTokenMock(address initialAccount, uint initialBalance) {
balances[initialAccount] = initialBalance;
totalSupply = initialBalance;
}
}
contracts/token/GrantableToken.sol
View file @
8d9e12ed
...
...
@@ -3,7 +3,7 @@ pragma solidity ^0.4.8;
import "./StandardToken.sol";
contract GrantableToken is StandardToken {
struct
Stock
Grant {
struct
Token
Grant {
address granter;
uint256 value;
uint64 cliff;
...
...
@@ -11,28 +11,28 @@ contract GrantableToken is StandardToken {
uint64 start;
}
mapping (address =>
Stock
Grant[]) public grants;
mapping (address =>
Token
Grant[]) public grants;
function grant
Stock
(address _to, uint256 _value) {
function grant
Tokens
(address _to, uint256 _value) {
transfer(_to, _value);
}
function grantVested
Stock
(address _to, uint256 _value, uint64 _start, uint64 _cliff, uint64 _vesting) {
function grantVested
Tokens
(address _to, uint256 _value, uint64 _start, uint64 _cliff, uint64 _vesting) {
if (_cliff < _start) throw;
if (_vesting < _start) throw;
if (_vesting < _cliff) throw;
StockGrant memory grant = Stock
Grant({start: _start, value: _value, cliff: _cliff, vesting: _vesting, granter: msg.sender});
TokenGrant memory grant = Token
Grant({start: _start, value: _value, cliff: _cliff, vesting: _vesting, granter: msg.sender});
grants[_to].push(grant);
grant
Stock
(_to, _value);
grant
Tokens
(_to, _value);
}
function revoke
Stock
Grant(address _holder, uint _grantId) {
Stock
Grant grant = grants[_holder][_grantId];
function revoke
Token
Grant(address _holder, uint _grantId) {
Token
Grant grant = grants[_holder][_grantId];
if (grant.granter != msg.sender) throw;
uint256 nonVested = nonVested
Share
s(grant, uint64(now));
uint256 nonVested = nonVested
Token
s(grant, uint64(now));
// remove grant from array
delete grants[_holder][_grantId];
...
...
@@ -43,12 +43,12 @@ contract GrantableToken is StandardToken {
balances[_holder] = safeSub(balances[_holder], nonVested);
}
function
stockGrant
Count(address _holder) constant returns (uint index) {
function
tokenGrants
Count(address _holder) constant returns (uint index) {
return grants[_holder].length;
}
function
stock
Grant(address _holder, uint _grantId) constant returns (address granter, uint256 value, uint256 vested, uint64 start, uint64 cliff, uint64 vesting) {
Stock
Grant grant = grants[_holder][_grantId];
function
token
Grant(address _holder, uint _grantId) constant returns (address granter, uint256 value, uint256 vested, uint64 start, uint64 cliff, uint64 vesting) {
Token
Grant grant = grants[_holder][_grantId];
granter = grant.granter;
value = grant.value;
...
...
@@ -56,26 +56,26 @@ contract GrantableToken is StandardToken {
cliff = grant.cliff;
vesting = grant.vesting;
vested = vested
Share
s(grant, uint64(now));
vested = vested
Token
s(grant, uint64(now));
}
function vested
Shares(StockGrant grant, uint64 time) private constant returns (uint256 vestedShare
s) {
function vested
Tokens(TokenGrant grant, uint64 time) private constant returns (uint256 vestedToken
s) {
if (time < grant.cliff) return 0;
if (time > grant.vesting) return grant.value;
uint256 cliff
Share
s = grant.value * uint256(grant.cliff - grant.start) / uint256(grant.vesting - grant.start);
vested
Shares = cliffShare
s;
uint256 cliff
Token
s = grant.value * uint256(grant.cliff - grant.start) / uint256(grant.vesting - grant.start);
vested
Tokens = cliffToken
s;
uint256 vesting
Shares = safeSub(grant.value, cliffShare
s);
uint256 vesting
Tokens = safeSub(grant.value, cliffToken
s);
vested
Shares = safeAdd(vestedShares, vestingShare
s * (time - uint256(grant.cliff)) / uint256(grant.vesting - grant.start));
vested
Tokens = safeAdd(vestedTokens, vestingToken
s * (time - uint256(grant.cliff)) / uint256(grant.vesting - grant.start));
}
function nonVested
Shares(Stock
Grant grant, uint64 time) private constant returns (uint256) {
return safeSub(grant.value, vested
Share
s(grant, time));
function nonVested
Tokens(Token
Grant grant, uint64 time) private constant returns (uint256) {
return safeSub(grant.value, vested
Token
s(grant, time));
}
function last
Stock
IsTransferrableEvent(address holder) constant public returns (uint64 date) {
function last
Token
IsTransferrableEvent(address holder) constant public returns (uint64 date) {
date = uint64(now);
uint256 grantIndex = grants[holder].length;
for (uint256 i = 0; i < grantIndex; i++) {
...
...
@@ -83,18 +83,18 @@ contract GrantableToken is StandardToken {
}
}
function transferrable
Share
s(address holder, uint64 time) constant public returns (uint256 nonVested) {
function transferrable
Token
s(address holder, uint64 time) constant public returns (uint256 nonVested) {
uint256 grantIndex = grants[holder].length;
for (uint256 i = 0; i < grantIndex; i++) {
nonVested = safeAdd(nonVested, nonVested
Share
s(grants[holder][i], time));
nonVested = safeAdd(nonVested, nonVested
Token
s(grants[holder][i], time));
}
return safeSub(balances[holder], nonVested);
}
function transfer(address _to, uint _value) returns (bool success){
if (_value > transferrable
Share
s(msg.sender, uint64(now))) throw;
if (_value > transferrable
Token
s(msg.sender, uint64(now))) throw;
return super.transfer(_to, _value);
}
...
...
package.json
View file @
8d9e12ed
...
...
@@ -12,6 +12,7 @@
},
"scripts"
:
{
"test"
:
"truffle test"
,
"console"
:
"truffle console"
,
"install"
:
"scripts/install.sh"
},
"repository"
:
{
...
...
test/AGrantableToken.js
deleted
100644 → 0
View file @
fb0a9633
const
assertJump
=
require
(
'./helpers/assertJump'
);
contract
(
'GrantableToken'
,
function
(
accounts
)
{
it
(
"should return the correct totalSupply after construction"
,
async
function
()
{
let
token
=
await
StandardTokenMock
.
new
(
accounts
[
0
],
100
);
let
totalSupply
=
await
token
.
totalSupply
();
assert
.
equal
(
totalSupply
,
100
);
})
it
(
"should return the correct allowance amount after approval"
,
async
function
()
{
let
token
=
await
StandardTokenMock
.
new
();
let
approve
=
await
token
.
approve
(
accounts
[
1
],
100
);
let
allowance
=
await
token
.
allowance
(
accounts
[
0
],
accounts
[
1
]);
assert
.
equal
(
allowance
,
100
);
});
it
(
"should return correct balances after transfer"
,
async
function
()
{
let
token
=
await
StandardTokenMock
.
new
(
accounts
[
0
],
100
);
let
transfer
=
await
token
.
transfer
(
accounts
[
1
],
100
);
let
balance0
=
await
token
.
balanceOf
(
accounts
[
0
]);
assert
.
equal
(
balance0
,
0
);
let
balance1
=
await
token
.
balanceOf
(
accounts
[
1
]);
assert
.
equal
(
balance1
,
100
);
});
it
(
"should throw an error when trying to transfer more than balance"
,
async
function
()
{
let
token
=
await
StandardTokenMock
.
new
(
accounts
[
0
],
100
);
try
{
let
transfer
=
await
token
.
transfer
(
accounts
[
1
],
101
);
}
catch
(
error
)
{
return
assertJump
(
error
);
}
assert
.
fail
(
'should have thrown before'
);
});
it
(
"should return correct balances after transfering from another account"
,
async
function
()
{
let
token
=
await
StandardTokenMock
.
new
(
accounts
[
0
],
100
);
let
approve
=
await
token
.
approve
(
accounts
[
1
],
100
);
let
transferFrom
=
await
token
.
transferFrom
(
accounts
[
0
],
accounts
[
2
],
100
,
{
from
:
accounts
[
1
]});
let
balance0
=
await
token
.
balanceOf
(
accounts
[
0
]);
assert
.
equal
(
balance0
,
0
);
let
balance1
=
await
token
.
balanceOf
(
accounts
[
2
]);
assert
.
equal
(
balance1
,
100
);
let
balance2
=
await
token
.
balanceOf
(
accounts
[
1
]);
assert
.
equal
(
balance2
,
0
);
});
it
(
"should throw an error when trying to transfer more than allowed"
,
async
function
()
{
let
token
=
await
StandardTokenMock
.
new
();
let
approve
=
await
token
.
approve
(
accounts
[
1
],
99
);
try
{
let
transfer
=
await
token
.
transferFrom
(
accounts
[
0
],
accounts
[
2
],
100
,
{
from
:
accounts
[
1
]});
}
catch
(
error
)
{
return
assertJump
(
error
);
}
assert
.
fail
(
'should have thrown before'
);
});
});
test/GrantableToken.js
0 → 100644
View file @
8d9e12ed
const
assertJump
=
require
(
'./helpers/assertJump'
);
const
timer
=
require
(
'./helpers/timer'
);
contract
(
'GrantableToken'
,
function
(
accounts
)
{
let
token
=
null
let
now
=
0
const
tokenAmount
=
50
const
granter
=
accounts
[
0
]
const
receiver
=
accounts
[
1
]
beforeEach
(
async
()
=>
{
token
=
await
GrantableTokenMock
.
new
(
granter
,
100
);
now
=
+
new
Date
()
/
1000
;
})
it
(
'granter can grant tokens without vesting'
,
async
()
=>
{
await
token
.
grantTokens
(
receiver
,
tokenAmount
,
{
from
:
granter
})
assert
.
equal
(
await
token
.
balanceOf
(
receiver
),
tokenAmount
);
assert
.
equal
(
await
token
.
transferrableTokens
(
receiver
,
+
new
Date
()
/
1000
),
tokenAmount
);
})
describe
(
'getting a token grant'
,
async
()
=>
{
const
cliff
=
1
const
vesting
=
2
// seconds
beforeEach
(
async
()
=>
{
await
token
.
grantVestedTokens
(
receiver
,
tokenAmount
,
now
,
now
+
cliff
,
now
+
vesting
,
{
from
:
granter
})
})
it
(
'tokens are received'
,
async
()
=>
{
assert
.
equal
(
await
token
.
balanceOf
(
receiver
),
tokenAmount
);
})
it
(
'has 0 transferrable tokens before cliff'
,
async
()
=>
{
assert
.
equal
(
await
token
.
transferrableTokens
(
receiver
,
now
),
0
);
})
it
(
'all tokens are transferrable after vesting'
,
async
()
=>
{
assert
.
equal
(
await
token
.
transferrableTokens
(
receiver
,
now
+
vesting
+
1
),
tokenAmount
);
})
it
(
'throws when trying to transfer non vested tokens'
,
async
()
=>
{
try
{
await
token
.
transfer
(
accounts
[
7
],
1
,
{
from
:
receiver
})
}
catch
(
error
)
{
return
assertJump
(
error
);
}
assert
.
fail
(
'should have thrown before'
);
})
it
(
'can be revoked by granter'
,
async
()
=>
{
await
token
.
revokeTokenGrant
(
receiver
,
0
,
{
from
:
granter
});
assert
.
equal
(
await
token
.
balanceOf
(
receiver
),
0
);
assert
.
equal
(
await
token
.
balanceOf
(
granter
),
100
);
})
it
(
'cannot be revoked by non granter'
,
async
()
=>
{
try
{
await
token
.
revokeTokenGrant
(
receiver
,
0
,
{
from
:
accounts
[
3
]
});
}
catch
(
error
)
{
return
assertJump
(
error
);
}
assert
.
fail
(
'should have thrown before'
);
})
it
(
'can be revoked by granter and non vested tokens are returned'
,
async
()
=>
{
await
timer
(
cliff
);
await
token
.
revokeTokenGrant
(
receiver
,
0
,
{
from
:
granter
});
assert
.
equal
(
await
token
.
balanceOf
(
receiver
),
tokenAmount
*
cliff
/
vesting
);
})
it
(
'can transfer all tokens after vesting ends'
,
async
()
=>
{
await
timer
(
vesting
+
1
);
await
token
.
transfer
(
accounts
[
7
],
tokenAmount
,
{
from
:
receiver
})
assert
.
equal
(
await
token
.
balanceOf
(
accounts
[
7
]),
tokenAmount
);
})
})
});
test/helpers/timer.js
0 → 100644
View file @
8d9e12ed
module
.
exports
=
s
=>
{
return
new
Promise
(
resolve
=>
{
setTimeout
(()
=>
resolve
(),
s
*
1000
+
600
)
// 600ms breathing room for testrpc to sync
})
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment