Better fee recycler contract

This commit is contained in:
Ricardo Guilherme Schmidt 2018-03-17 10:35:02 -03:00
parent a03e3b514b
commit 94214f9907
3 changed files with 89 additions and 72 deletions

View File

@ -1,46 +0,0 @@
pragma solidity ^0.4.17;
import "../token/MiniMeToken.sol";
import "../token/ApproveAndCallFallBack.sol";
contract BurnedFeeLocker is ApproveAndCallFallBack {
address public SNT;
address public recyclerManager;
mapping (address => uint256) burnedFee;
uint256 availableToRecycle;
function BurnedFeeLocker(address _recyclerManager, address _SNT) public {
SNT = _SNT;
recyclerManager = _recyclerManager;
}
function recycleFee(address _from, address _to, uint256 _amount) external {
require(msg.sender == recyclerManager);
require(burnedFee[_from] >= _amount);
MiniMeToken(SNT).approveAndCall(_to, _amount, new bytes(0));
availableToRecycle -= _amount;
}
function withdrawToken(address _token, address _to) external {
require(msg.sender == recyclerManager);
uint256 available = MiniMeToken(_token).balanceOf(address(this));
if (_token == SNT) {
available -= availableToRecycle;
}
if (available > 0) {
MiniMeToken(_token).transfer(_to, available);
}
}
function receiveApproval(address _from, uint256 _amount, address _token, bytes _data) public {
require(_token == SNT);
if (_amount == 0 || _data.length > 0) {
require(msg.sender == _token);
}
if (MiniMeToken(SNT).transferFrom(_from, address(this), _amount)) {
burnedFee[_from] += _amount;
availableToRecycle += _amount;
}
}
}

View File

@ -0,0 +1,89 @@
pragma solidity ^0.4.17;
import "../common/Controlled.sol";
import "../token/ERC20Token.sol";
import "../token/MiniMeToken.sol";
/**
* @title FeeRecycler
* @author Ricardo Guilherme Schmidt (Status Research & Development GmBH)
* @dev Allow user selecting predefined destinations to where this fees will be invested
*/
contract FeeRecycler is Controlled {
//allowed democratically choosen destinations
mapping (address => bool) public destinations;
//balances of users
mapping (address => uint256) public balances;
//used for withdrawing lost tokens
uint256 public totalLocked;
//base token
MiniMeToken public token;
/**
* @notice Constructor defines the unchangable (?) baseToken
* @param _token base token
*/
function FeeRecycler(MiniMeToken _token) public {
token = _token;
}
/**
* @notice Lock a fee in name of someone
* @param _from who would be able to recycle this funds
* @param _amount to be locked
*/
function lock(address _from, uint256 _amount) external {
require(token.transferFrom(msg.sender, address(this), _amount));
balances[_from] += _amount;
totalLocked += _amount;
}
/**
* @notice Unlock and approveAndCall
* @param _to Allowed destination to get tokens
* @param _amount that will be transfered
*/
function recycle(address _to, uint256 _amount) external {
require(destinations[_to]);
require(balances[msg.sender] >= _amount);
balances[msg.sender] -= _amount;
totalLocked -= _amount;
token.approveAndCall(_to, _amount, new bytes(0));
}
/**
* @notice Controller should enable destinations to recycle
* @param _destination that would be available to recycle
* @param _allowed users can recycle to this address?
*/
function setDestination(address _destination, bool _allowed)
external
onlyController
{
destinations[_destination] = _allowed;
}
/**
* @notice Withdraw lost tokens in the contract
* @param _token if is base token than can only transfer unlocked amount
* @param _destination address receiving this tokens
* @param _amount the amount to be transfered
*/
function withdraw(ERC20Token _token, address _destination, uint256 _amount)
external
onlyController
{
if (address(_token) == address(token)) {
require(_amount <= _token.balanceOf(address(this)) - totalLocked);
} else if (address(_token) == address(0)) {
require(this.balance <= _amount);
}
if (address(_token) != address(0)) {
_token.transfer(_destination, _amount);
} else {
_destination.transfer(_amount);
}
}
}

View File

@ -1,26 +0,0 @@
pragma solidity ^0.4.17;
import "../common/Controlled.sol";
import "./BurnedFeeLocker.sol";
contract RecyclerManager is Controlled {
address burnContract;
mapping (address => bool) bounties;
function RecyclerManager(address _burnContract) public {
burnContract = _burnContract;
}
function recycleFeeIntoSOB(address bounty, uint256 amount) external {
require(bounties[bounty]);
BurnedFeeLocker(burnContract).recycleFee(msg.sender, bounty, amount);
}
function setBounty(address bounty, bool enabled) external onlyController {
bounties[bounty] = enabled;
}
}