Skip to content
This repository was archived by the owner on Jun 15, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions contracts/BondingCurve/interface/IRewardsDistributor.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
pragma solidity ^0.5.6;

contract IRewardsDistributor {
/// @notice Deposit funds into contract.
function deposit(address staker, uint256 tokens) public returns (bool success);

/// @notice Distribute tokens pro rata to all stakers.
function distribute(address from, uint256 tokens) public returns (bool success);

/// @notice Withdraw accumulated reward for the staker address.
function withdrawReward(address staker) public returns (uint256 tokens);

/// @notice Withdraw stake for the staker address
function withdrawStake(address staker, uint256 tokens) public returns (bool);

/// @notice Withdraw stake for the staker address
function withdrawAllStake(address staker) public returns (bool);

///
/// READ ONLY
///

/// @notice Read total stake.
function getStakeTotal() public view returns (uint256);
/// @notice Read current stake for address.
function getStake(address staker) public view returns (uint256 tokens);

/// @notice Read current accumulated reward for address.
function getReward(address staker) public view returns (uint256 tokens);

}
10 changes: 10 additions & 0 deletions contracts/BondingCurve/interface/IRewardsWalletEther.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
pragma solidity ^0.5.6;

import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol";

contract IRewardsWalletEther {
/// @notice Deposit funds into contract.
function exchangeAndDistribute(IERC20 token, uint256 amount, uint256 minOut, uint256 deadline)
external
returns (uint256 amountOut);
}
146 changes: 146 additions & 0 deletions contracts/BondingCurve/interface/IUniswapExchange.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
pragma solidity ^0.5.7;

// Solidity Interface
// https://docs.uniswap.io/smart-contract-integration/interface

contract IUniswapExchange {
// Address of ERC20 token sold on this exchange
function tokenAddress() external view returns (address token);
// Address of Uniswap Factory
function factoryAddress() external view returns (address factory);
// Provide Liquidity
function addLiquidity(uint256 min_liquidity, uint256 max_tokens, uint256 deadline)
external
payable
returns (uint256);
function removeLiquidity(uint256 amount, uint256 min_eth, uint256 min_tokens, uint256 deadline)
external
returns (uint256, uint256);
// Get Prices
function getEthToTokenInputPrice(uint256 eth_sold)
external
view
returns (uint256 tokens_bought);
function getEthToTokenOutputPrice(uint256 tokens_bought)
external
view
returns (uint256 eth_sold);
function getTokenToEthInputPrice(uint256 tokens_sold)
external
view
returns (uint256 eth_bought);
function getTokenToEthOutputPrice(uint256 eth_bought)
external
view
returns (uint256 tokens_sold);
// Trade ETH to ERC20
function ethToTokenSwapInput(uint256 min_tokens, uint256 deadline)
external
payable
returns (uint256 tokens_bought);
function ethToTokenTransferInput(uint256 min_tokens, uint256 deadline, address recipient)
external
payable
returns (uint256 tokens_bought);
function ethToTokenSwapOutput(uint256 tokens_bought, uint256 deadline)
external
payable
returns (uint256 eth_sold);
function ethToTokenTransferOutput(uint256 tokens_bought, uint256 deadline, address recipient)
external
payable
returns (uint256 eth_sold);
// Trade ERC20 to ETH
function tokenToEthSwapInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline)
external
returns (uint256 eth_bought);
function tokenToEthTransferInput(
uint256 tokens_sold,
uint256 min_eth,
uint256 deadline,
address recipient
) external returns (uint256 eth_bought);
function tokenToEthSwapOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline)
external
returns (uint256 tokens_sold);
function tokenToEthTransferOutput(
uint256 eth_bought,
uint256 max_tokens,
uint256 deadline,
address recipient
) external returns (uint256 tokens_sold);
// Trade ERC20 to ERC20
function tokenToTokenSwapInput(
uint256 tokens_sold,
uint256 min_tokens_bought,
uint256 min_eth_bought,
uint256 deadline,
address token_addr
) external returns (uint256 tokens_bought);
function tokenToTokenTransferInput(
uint256 tokens_sold,
uint256 min_tokens_bought,
uint256 min_eth_bought,
uint256 deadline,
address recipient,
address token_addr
) external returns (uint256 tokens_bought);
function tokenToTokenSwapOutput(
uint256 tokens_bought,
uint256 max_tokens_sold,
uint256 max_eth_sold,
uint256 deadline,
address token_addr
) external returns (uint256 tokens_sold);
function tokenToTokenTransferOutput(
uint256 tokens_bought,
uint256 max_tokens_sold,
uint256 max_eth_sold,
uint256 deadline,
address recipient,
address token_addr
) external returns (uint256 tokens_sold);
// Trade ERC20 to Custom Pool
function tokenToExchangeSwapInput(
uint256 tokens_sold,
uint256 min_tokens_bought,
uint256 min_eth_bought,
uint256 deadline,
address exchange_addr
) external returns (uint256 tokens_bought);
function tokenToExchangeTransferInput(
uint256 tokens_sold,
uint256 min_tokens_bought,
uint256 min_eth_bought,
uint256 deadline,
address recipient,
address exchange_addr
) external returns (uint256 tokens_bought);
function tokenToExchangeSwapOutput(
uint256 tokens_bought,
uint256 max_tokens_sold,
uint256 max_eth_sold,
uint256 deadline,
address exchange_addr
) external returns (uint256 tokens_sold);
function tokenToExchangeTransferOutput(
uint256 tokens_bought,
uint256 max_tokens_sold,
uint256 max_eth_sold,
uint256 deadline,
address recipient,
address exchange_addr
) external returns (uint256 tokens_sold);
// ERC20 comaptibility for liquidity tokens
bytes32 public name;
bytes32 public symbol;
uint256 public decimals;
function transfer(address _to, uint256 _value) external returns (bool);
function transferFrom(address _from, address _to, uint256 value) external returns (bool);
function approve(address _spender, uint256 _value) external returns (bool);
function allowance(address _owner, address _spender) external view returns (uint256);
function balanceOf(address _owner) external view returns (uint256);
function totalSupply() external view returns (uint256);
// Never use
function setup(address token_addr) external;
}
65 changes: 65 additions & 0 deletions contracts/BondingCurve/wallet/RewardsWalletERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
pragma solidity ^0.5.6;

import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol";
import "contracts/BondingCurve/interface/IRewardsDistributor.sol";
import "contracts/BondingCurve/interface/IUniswapExchange.sol";

/**
* @title RewardsWalletERC20
*/
contract RewardsWalletERC20 is Initializable {
using SafeMath for uint256;

IERC20 _rewardsToken;
IRewardsDistributor _rewardsDistributor;
IUniswapExchange _exchange;

string internal constant ONLY_REWARDS_TOKEN = "Only Rewards Token";
string internal constant ONLY_FOR_ETHER_REWARDS_TOKEN = "Only functional for Ether as rewards currency";

event Recieve(address token, uint256 amount, address sender);
event Convert(address fromToken, address toToken, uint256 amount);
event Distribute(address token, uint256 amount);

/// Initialize the contract.
function initialize(
IERC20 rewardsToken,
IRewardsDistributor rewardsDistributor,
IUniswapExchange exchange
) public initializer {
_rewardsToken = rewardsToken;
_rewardsDistributor = rewardsDistributor;
_exchange = exchange;
}

/// @dev Recieve payment and immediately distribute. Requires previous approval
function pay(IERC20 token, uint256 amount) public {
token.transferFrom(msg.sender, address(this), amount);
_distribute(token, amount);
}

/// @notice Distribute wallet balance of specified token to dividend holders
/// @dev This has open access, can be used to distribte tokens recieved on native ERC20 transfers
/// @dev Tokens other than the reserve currency will be transferred via the exchange.
function distribute(IERC20 token) public {
require(_isRewardsToken(token), ONLY_REWARDS_TOKEN);
uint256 walletBalance = token.balanceOf(address(this));
_distribute(token, walletBalance);
}

function _distribute(IERC20 token, uint256 amount) internal {
require(_isRewardsToken(token), ONLY_REWARDS_TOKEN);
token.approve(address(_rewardsToken), amount);
_rewardsDistributor.distribute(address(this), amount);
}

function _isRewardsToken(IERC20 token) internal returns (bool) {
return address(token) == address(_rewardsToken);
}

function _isEtherAddress(address tokenAddress) internal returns (bool) {
return tokenAddress == address(0);
}
}
60 changes: 60 additions & 0 deletions contracts/BondingCurve/wallet/RewardsWalletEther.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
pragma solidity ^0.5.6;

import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol";
import "contracts/BondingCurve/interface/IRewardsWalletEther.sol";
import "contracts/BondingCurve/interface/IRewardsDistributor.sol";
import "contracts/BondingCurve/interface/IUniswapExchange.sol";

/**
* @title RewardsWalletEther
*/
contract RewardsWalletEther is Initializable, IRewardsWalletEther {
using SafeMath for uint256;

IRewardsDistributor _rewardsDistributor;
IUniswapExchange _exchangeContract;

string internal constant ONLY_REWARDS_TOKEN = "Only Rewards Token";
string internal constant ONLY_FOR_ETHER_REWARDS_TOKEN = "Only functional for Ether as rewards currency";

event Receive(address token, uint256 amount, address sender);
event Convert(address fromToken, address toToken, uint256 amount);
event Distribute(address token, uint256 amount);

/// Initialize the contract.
function initialize(IRewardsDistributor rewardsDistributor, IUniswapExchange exchangeContract)
public
initializer
{
_rewardsDistributor = rewardsDistributor;
_exchangeContract = exchangeContract;
}

/// @notice Distribute wallet balance of specified token to dividend holders
/// @dev This has open access, can be used to distribte tokens recieved on native ERC20 transfers
/// @dev Tokens other than the reserve currency will be transferred via the exchange.
function exchangeAndDistribute(IERC20 token, uint256 amount, uint256 minOut, uint256 deadline)
external
returns (uint256 amountOut)
{
token.approve(address(_exchangeContract), amount);
amountOut = _exchangeContract.tokenToEthSwapInput(amount, minOut, deadline);

emit Receive(address(0), amountOut, msg.sender);
_distribute(amountOut);
}

function _distribute(uint256 amount) internal {
address(uint160(address(_rewardsDistributor))).transfer(amount);
_rewardsDistributor.distribute(address(this), amount);
emit Distribute(address(0), amount);
}

/// @notice Automatically distribute ETH on payments
function() external payable {
emit Receive(address(0), msg.value, msg.sender);
_distribute(msg.value);
}
}
Loading