forked from JoinColony/colonyNetwork
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request JoinColony#253 from filiplazovic/feature/token-loc…
…king Token Locking
- Loading branch information
Showing
16 changed files
with
852 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
pragma solidity ^0.4.23; | ||
|
||
|
||
contract ITokenLocking { | ||
|
||
/// @notice Set the ColonyNetwork contract address | ||
/// @dev ColonyNetwork is used for checking if sender is a colony created on colony network | ||
/// @param _colonyNetwork Address of the ColonyNetwork | ||
function setColonyNetwork(address _colonyNetwork) public; | ||
|
||
/// @notice Get ColonyNetwork address | ||
/// @return ColonyNetwork address | ||
function getColonyNetwork() public view returns (address); | ||
|
||
/// @notice Locks everyones' tokens on `_token` address | ||
/// @param _token Address of the token we want to lock | ||
/// @return Updated total token lock count | ||
function lockToken(address _token) public returns (uint256); | ||
|
||
/// @notice Increments the lock counter to `_lockId` for the `_user` if user's lock count is less than `_lockId` by 1. | ||
/// Can only be called by a colony | ||
/// @param _token Address of the token we want to unlock | ||
/// @param _user Address of the user | ||
/// @param _lockId Id of the lock we want to increment to | ||
function unlockTokenForUser(address _token, address _user, uint256 _lockId) public; | ||
|
||
/// @notice Increments sender's lock count to `_lockId`. | ||
/// @param _token Address of the token we want to increment lock count for | ||
/// @param _lockId Id of the lock user wants to increment to | ||
function incrementLockCounterTo(address _token, uint256 _lockId) public; | ||
|
||
/// @notice Deposit `_amount` of colony tokens. Can only be called if user tokens are not locked | ||
/// Before calling this function user has to allow that their tokens can be transferred by token locking contract | ||
/// @param _amount Amount to deposit | ||
function deposit(address _token, uint256 _amount) public; | ||
|
||
/// @notice Withdraw `_amount` of deposited tokens. Can only be called if user tokens are not locked | ||
/// @param _amount Amount to withdraw | ||
function withdraw(address _token, uint256 _amount) public; | ||
|
||
/// @notice Get global lock count for a specific token | ||
/// @param _token Address of the token | ||
/// @return Global token lock count | ||
function getTotalLockCount(address _token) public view returns (uint256); | ||
|
||
/// @notice Get user token lock info (lock count and deposited amount) | ||
/// @param _token Address of the token | ||
/// @param _user Address of the user | ||
/// @return User's token lock count | ||
/// @return User's deposited amount | ||
function getUserLock(address _token, address _user) public view returns (uint256, uint256); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
pragma solidity ^0.4.23; | ||
|
||
import "./ERC20Extended.sol"; | ||
import "./IColonyNetwork.sol"; | ||
import "./TokenLockingStorage.sol"; | ||
import "../lib/dappsys/math.sol"; | ||
|
||
|
||
contract TokenLocking is TokenLockingStorage, DSMath { | ||
modifier onlyColony() { | ||
require(IColonyNetwork(colonyNetwork).isColony(msg.sender), "token-locking-sender-not-colony"); | ||
_; | ||
} | ||
|
||
modifier tokenNotLocked(address _token) { | ||
if (userLocks[_token][msg.sender].balance > 0) { | ||
require(userLocks[_token][msg.sender].lockCount == totalLockCount[_token], "token-locking-token-locked"); | ||
} | ||
_; | ||
} | ||
|
||
function setColonyNetwork(address _colonyNetwork) public auth { | ||
colonyNetwork = _colonyNetwork; | ||
} | ||
|
||
function getColonyNetwork() public view returns (address) { | ||
return colonyNetwork; | ||
} | ||
|
||
function lockToken(address _token) public onlyColony returns (uint256) { | ||
totalLockCount[_token] += 1; | ||
return totalLockCount[_token]; | ||
} | ||
|
||
function unlockTokenForUser(address _token, address _user, uint256 _lockId) public onlyColony { | ||
require(sub(_lockId, userLocks[_token][_user].lockCount) == 1, "token-locking-invalid-lock-id"); | ||
// If we want to unlock tokens at id greater than total lock count, we are doing something wrong | ||
assert(_lockId <= totalLockCount[_token]); | ||
userLocks[_token][_user].lockCount = _lockId; | ||
} | ||
|
||
function incrementLockCounterTo(address _token, uint256 _lockId) public { | ||
require(_lockId <= totalLockCount[_token] && _lockId > userLocks[_token][msg.sender].lockCount, "token-locking-invalid-lock-id"); | ||
userLocks[_token][msg.sender].lockCount = _lockId; | ||
} | ||
|
||
function deposit(address _token, uint256 _amount) public | ||
tokenNotLocked(_token) | ||
{ | ||
require(_amount > 0, "token-locking-invalid-amount"); | ||
|
||
require(ERC20Extended(_token).transferFrom(msg.sender, address(this), _amount), "token-locking-transfer-failed"); | ||
|
||
userLocks[_token][msg.sender] = Lock(totalLockCount[_token], add(userLocks[_token][msg.sender].balance, _amount)); | ||
} | ||
|
||
function withdraw(address _token, uint256 _amount) public | ||
tokenNotLocked(_token) | ||
{ | ||
require(_amount > 0, "token-locking-invalid-amount"); | ||
|
||
userLocks[_token][msg.sender].balance = sub(userLocks[_token][msg.sender].balance, _amount); | ||
|
||
require(ERC20Extended(_token).transfer(msg.sender, _amount), "token-locking-transfer-failed"); | ||
} | ||
|
||
function getTotalLockCount(address _token) public view returns (uint256) { | ||
return totalLockCount[_token]; | ||
} | ||
|
||
function getUserLock(address _token, address _user) public view returns (uint256, uint256) { | ||
return (userLocks[_token][_user].lockCount, userLocks[_token][_user].balance); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
pragma solidity ^0.4.23; | ||
|
||
import "../lib/dappsys/auth.sol"; | ||
|
||
|
||
contract TokenLockingStorage is DSAuth { | ||
address resolver; | ||
|
||
// Address of ColonyNetwork contract | ||
address colonyNetwork; | ||
|
||
struct Lock { | ||
// Users lock count | ||
uint256 lockCount; | ||
// Deposited balance | ||
uint256 balance; | ||
} | ||
|
||
// Maps token to user to Lock struct | ||
mapping (address => mapping (address => Lock)) userLocks; | ||
|
||
// Maps token to total token lock count. If user token lock count is the same as global, that means that their tokens are unlocked. | ||
// If user token lock count is less than global, that means that their tokens are locked. | ||
// User's lock count should never be greater than total lock count. | ||
mapping (address => uint256) totalLockCount; | ||
} |
Oops, something went wrong.