From 72deab2331ca24c5c69bd9a909a0af599827171d Mon Sep 17 00:00:00 2001 From: Ricardo Guilherme Schmidt <3esmit@gmail.com> Date: Sat, 17 Mar 2018 10:35:02 -0300 Subject: [PATCH] Better fee recycler contract --- contracts/democracy/BurnedFeeLocker.sol | 46 ------------- contracts/democracy/FeeRecycler.sol | 89 +++++++++++++++++++++++++ contracts/democracy/RecyclerManager.sol | 26 -------- 3 files changed, 89 insertions(+), 72 deletions(-) delete mode 100644 contracts/democracy/BurnedFeeLocker.sol create mode 100644 contracts/democracy/FeeRecycler.sol delete mode 100644 contracts/democracy/RecyclerManager.sol diff --git a/contracts/democracy/BurnedFeeLocker.sol b/contracts/democracy/BurnedFeeLocker.sol deleted file mode 100644 index 96d9db3..0000000 --- a/contracts/democracy/BurnedFeeLocker.sol +++ /dev/null @@ -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; - } - } -} \ No newline at end of file diff --git a/contracts/democracy/FeeRecycler.sol b/contracts/democracy/FeeRecycler.sol new file mode 100644 index 0000000..7011a77 --- /dev/null +++ b/contracts/democracy/FeeRecycler.sol @@ -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); + } + } + +} \ No newline at end of file diff --git a/contracts/democracy/RecyclerManager.sol b/contracts/democracy/RecyclerManager.sol deleted file mode 100644 index ab1d079..0000000 --- a/contracts/democracy/RecyclerManager.sol +++ /dev/null @@ -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; - } - - - -} \ No newline at end of file