2019-06-18 12:14:29 +00:00
|
|
|
pragma solidity ^0.5.0;
|
|
|
|
|
2019-06-18 13:59:23 +00:00
|
|
|
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
|
2019-06-18 12:14:29 +00:00
|
|
|
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
|
|
|
|
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";
|
|
|
|
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Burnable.sol";
|
2019-06-18 19:56:50 +00:00
|
|
|
import "./math.sol";
|
|
|
|
import "./token/ApproveAndCallFallBack.sol";
|
2019-06-18 12:14:29 +00:00
|
|
|
|
2019-06-18 19:56:50 +00:00
|
|
|
contract StakingPool is ERC20, ERC20Detailed, ERC20Burnable, DSMath, ApproveAndCallFallBack {
|
2019-06-18 12:14:29 +00:00
|
|
|
uint private INITIAL_SUPPLY = 0;
|
2019-06-18 13:59:23 +00:00
|
|
|
IERC20 public token;
|
2019-06-18 12:14:29 +00:00
|
|
|
|
2019-06-18 13:59:23 +00:00
|
|
|
constructor (address tokenAddress) public ERC20Detailed("TellerStatus", "TSNT", 18) {
|
|
|
|
token = IERC20(tokenAddress);
|
2019-06-18 12:14:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function exchangeRate (uint256 excludeAmount) public view returns (uint256) {
|
|
|
|
if (totalSupply() == 0) return 1000000000000000000;
|
2019-06-18 13:59:23 +00:00
|
|
|
return wdiv(token.balanceOf(address(this)), totalSupply());
|
2019-06-18 12:14:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function estimatedTokens(uint256 value) public view returns (uint256) {
|
|
|
|
uint256 rate = exchangeRate(value);
|
|
|
|
return wdiv(value, wdiv(rate, 1000000000000000000));
|
|
|
|
}
|
|
|
|
|
2019-06-18 13:59:23 +00:00
|
|
|
function deposit (uint256 amount) public payable {
|
2019-06-18 19:56:50 +00:00
|
|
|
_deposit(msg.sender, amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
function _deposit(address _from, uint256 amount) internal {
|
2019-06-18 13:59:23 +00:00
|
|
|
uint256 equivalentTokens = estimatedTokens(amount);
|
2019-06-18 19:56:50 +00:00
|
|
|
require(token.transferFrom(_from, address(this), amount), "Couldn't transfer");
|
|
|
|
_mint(_from, equivalentTokens);
|
2019-06-18 12:14:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function withdraw (uint256 amount) public {
|
|
|
|
uint256 rate = exchangeRate(0);
|
|
|
|
burn(amount);
|
2019-06-18 19:56:50 +00:00
|
|
|
require(token.transfer(msg.sender, wmul(amount, wdiv(rate, 1000000000000000000))), "Couldn't transfer");
|
2019-06-18 13:59:23 +00:00
|
|
|
}
|
2019-06-18 12:14:29 +00:00
|
|
|
|
2019-06-18 19:56:50 +00:00
|
|
|
/**
|
|
|
|
* @notice Support for "approveAndCall". Callable only by `token()`.
|
|
|
|
* @param _from Who approved.
|
|
|
|
* @param _amount Amount being approved,
|
|
|
|
* @param _token Token being approved, need to be equal `token()`.
|
|
|
|
* @param _data Abi encoded data`.
|
|
|
|
*/
|
|
|
|
function receiveApproval(address _from, uint256 _amount, address _token, bytes memory _data) public {
|
|
|
|
require(_token == address(token), "Wrong token");
|
|
|
|
require(_token == address(msg.sender), "Wrong call");
|
|
|
|
require(_data.length == 36, "Wrong data length");
|
|
|
|
|
|
|
|
bytes4 sig;
|
|
|
|
uint amount;
|
|
|
|
(sig, amount) = abiDecodeRegister(_data);
|
|
|
|
|
|
|
|
require(amount == _amount, "Amounts mismatch");
|
|
|
|
require(sig == 0xb6b55f25, "Wrong method selector"); // deposit(uint256)
|
|
|
|
_deposit(_from, amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
function abiDecodeRegister(bytes memory _data) private returns(
|
|
|
|
bytes4 sig,
|
|
|
|
uint256 amount
|
|
|
|
) {
|
|
|
|
assembly {
|
|
|
|
sig := mload(add(_data, add(0x20, 0)))
|
|
|
|
amount := mload(add(_data, 36))
|
|
|
|
}
|
|
|
|
}
|
2019-06-18 12:14:29 +00:00
|
|
|
}
|