Skip to content

Commit

Permalink
more docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Turupawn committed Feb 2, 2023
1 parent 2d9183e commit 2edd9e7
Show file tree
Hide file tree
Showing 8 changed files with 449 additions and 51 deletions.
45 changes: 33 additions & 12 deletions contracts/ERC20/BalancerV2FeeToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ pragma solidity ^0.8.0;
import "./ERC20.sol";
import "./interfaces/BalancerInterfaces.sol";

/// @title ERC20 token that takes fees on P2P, buy and sell on Balancer and transfer them to a Vault.
/// @title ERC20 token that takes fees on P2P, buy and sell on Balancer and transfer them to the feeReceiver.
/// @author Filosofía Codigo
/// @notice You can use this contract launch your own token or to study the Balancer ecosystem
/// @notice You can use this contract launch your own token or to study the Balancer ecosystem.
/// @dev Based on top OpenZeppelin contracts but changed balances from private to internal for flexibility
/// @custom:experimental This is an experimental contract.
abstract contract BalancerV2FeeToken is ERC20
{
/// @notice List of address that won't pay transaction fees
Expand Down Expand Up @@ -84,16 +83,38 @@ abstract contract BalancerV2FeeToken is ERC20

/// @notice Set excemptions for transaction fee payments
/// @param account Address that tax configuration will be affected
/// @param value If set to true the account will not pay transaction fees
/// @custom:ownable This function can only be executed by the contract owner.
function setTaxless(address account, bool value) external onlyOwner {
isTaxless[account] = value;
/// @param isTaxless_ If set to true the account will not pay transaction fees
/// @custom:internal This function is internal, can be overrided.
function _setTaxless(address account, bool isTaxless_) internal
{
isTaxless[account] = isTaxless_;
}

/// @notice Changes the address that will recieve fees
/// @param feeReceiver_ If set to true the account will not pay transaction fees
/// @custom:internal This function is internal, can be overrided.
function _setFeeReceiver(address feeReceiver_) internal
{
feeReceiver = feeReceiver_;
}

/// @notice Set excemptions for all transaction fee payments
/// @param value If set to true all transaction fees will not be charged
/// @custom:ownable This function can only be executed by the contract owner.
function setFeeActive(bool value) public onlyOwner {
isFeeActive = value;
/// @notice Changes the address that will recieve fees
/// @param isFeeActive_ If set to true all transaction fees will not be charged
/// @custom:internal This function is internal, can be overrided.
function _setFeeActive(bool isFeeActive_) internal
{
isFeeActive = isFeeActive_;
}

/// @notice The fee percentage for buy, sell and peer to peer
/// @param buyFeePercentage New buy percentage fee
/// @param sellFeePercentage New sell percentage fee
/// @param p2pFeePercentage New peer to peer percentage fee
/// @custom:internal This function is internal, can be overrided.
function _setFees(uint buyFeePercentage, uint sellFeePercentage, uint p2pFeePercentage) internal
{
fees[0] = buyFeePercentage;
fees[1] = sellFeePercentage;
fees[2] = p2pFeePercentage;
}
}
25 changes: 25 additions & 0 deletions contracts/ERC20/UniswapV2AutoSwapToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,33 @@ pragma solidity ^0.8.0;
import "./UniswapV2FeeToken.sol";
import "./interfaces/UniswapV2Interfaces.sol";

/// @title ERC20 token that takes fees on P2P, buy and sell on a Uniswap V2 contract and then transfers the collected fees to a autoSwapReciever address in the form of base tokens.
/// @author Filosofía Codigo
/// @notice You can use this contract launch your own token or to study the Uniswap V2 ecosystem.
/// @dev Based on top OpenZeppelin contracts but changed balances from private to internal for flexibility
abstract contract UniswapV2AutoSwapToken is UniswapV2FeeToken
{
/// @notice Percentage of total supply that have to be accumulated as fees to trigger the autoswap and send the fees to the autoSwapReciever
uint256 public minTokensBeforeSwap;
/// @notice Address that will recieve fees on base token denomination
address public autoSwapReciever;
/// @dev Internal flag that prevents infinite recursion during the autoswap
bool lastFeeActive;
/// @dev Event emited during the autoswap
event Swap(uint amountSent);

/// @notice Contract constructor
/// @dev All percentage numbers are two digit decimals. For example 250 means 2.5%
/// @param name Token Name
/// @param symbol Token Symbol
/// @param totalSupply_ Total supply, all supply will be sent to contract deployer
/// @param buyFeePercentage Percent of tokens that will be sent to the feeReciever when token is bought on Uniswap V2
/// @param sellFeePercentage Percent of tokens that will be sent to the feeReciever when token is sold on Uniswap V2
/// @param p2pFeePercentage Percent of tokens that will be sent to the feeReciever when token is transfered outside of Uniswap V2
/// @param autoSwapReciever_ Address that will recieve the fees taken every transaction
/// @param routerAddress You can support such DEXes by setting the router address in this param. Many projects such as Pancakeswap, Sushiswap or Quickswap are compatible with Uniswap V2
/// @param baseTokenAddress Token address that this will be paired with on the DEX. Fees will be sent to the autoSwapReciever in the base token denomination
/// @param minTokensBeforeSwapPercent Percentage of total supply that have to be accumulated as fees to trigger the autoswap and send the fees to the autoSwapReciever
constructor(string memory name, string memory symbol,
uint totalSupply_,
uint buyFeePercentage, uint sellFeePercentage, uint p2pFeePercentage,
Expand All @@ -31,13 +51,15 @@ abstract contract UniswapV2AutoSwapToken is UniswapV2FeeToken
setMinTokensBeforeSwapPercent(minTokensBeforeSwapPercent);
}

/// @dev internal modifier to prevent infinite recursion while executing the autoswap
modifier lockTheSwap() {
lastFeeActive = isFeeActive;
_setFeeActive(false);
_;
_setFeeActive(lastFeeActive);
}

/// @dev Swaps all the fees collected to base tokens and send it to the autoSwapReciever
function swap() private lockTheSwap {
uint totalSwap = balanceOf(address(this));
if(minTokensBeforeSwap > totalSwap) return;
Expand All @@ -59,6 +81,7 @@ abstract contract UniswapV2AutoSwapToken is UniswapV2FeeToken
emit Swap(totalSwap);
}

/// @notice This functions is inherited from OpenZeppelin and UniswapV2FeeToken that runs the autoswap in case it's ready to be executed
function _transfer(
address from,
address to,
Expand All @@ -71,6 +94,8 @@ abstract contract UniswapV2AutoSwapToken is UniswapV2FeeToken
super._transfer(from, to, amount);
}

/// @notice Change the minimum ammount of fees collected to trigger the autoswap
/// @param percentage Percentage of total supply that have to be accumulated as fees to trigger the autoswap and send the fees to the autoSwapReciever
function setMinTokensBeforeSwapPercent(uint256 percentage) public onlyOwner {
minTokensBeforeSwap = (totalSupply() * percentage) / (10**(feeDecimals + 2));
}
Expand Down
58 changes: 50 additions & 8 deletions contracts/ERC20/UniswapV2FeeToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,40 @@ pragma solidity ^0.8.0;
import "./ERC20.sol";
import "./interfaces/UniswapV2Interfaces.sol";

/// @title ERC20 token that takes fees on P2P, buy and sell on Uniswap V2 and transfer them to a the feeReceiver.
/// @author Filosofía Codigo
/// @notice You can use this contract launch your own token or to study the Uniswap V2 ecosystem.
/// @dev Based on top OpenZeppelin contracts but changed balances from private to internal for flexibility
abstract contract UniswapV2FeeToken is ERC20
{
/// @notice List of address that won't pay transaction fees
mapping(address => bool) public isTaxless;
/// @notice Address that will recieve fees taken from each transaction
address public feeReceiver;
/// @notice If set to true, no fees will be taken on any transaction
bool public isFeeActive;
/// @notice Array that defines the transactions fees. Index 0 is buy fee, 1 is sell fee and 2 is peer to peer fee
uint[] public fees;
/// @notice Number if fee decimals. Default is 2 so for example 250 means 2.5% in percentage numbers
uint public feeDecimals = 2;
/// @notice Uniswap V2 Pair formed by this token and the base token
address public pair;
/// @notice Uniswap V2 Router address
ISwapRouter router;
/// @notice Token that will be paired with this token when liquidity is added to the DEX
IERC20 baseToken;


/// @notice Contract constructor
/// @dev All percentage numbers are two digit decimals. For example 250 means 2.5%
/// @param name Token Name
/// @param symbol Token Symbol
/// @param totalSupply_ Total supply, all supply will be sent to contract deployer
/// @param buyFeePercentage Percent of tokens that will be sent to the feeReciever when token is bought on Uniswap V2
/// @param sellFeePercentage Percent of tokens that will be sent to the feeReciever when token is sold on Uniswap V2
/// @param p2pFeePercentage Percent of tokens that will be sent to the feeReciever when token is transfered outside of Uniswap V2
/// @param feeReceiver_ Address that will recieve the fees taken every transaction
/// @param routerAddress You can support such DEXes by setting the router address in this param. Many projects such as Pancakeswap, Sushiswap or Quickswap are compatible with Uniswap V2
/// @param baseTokenAddress Token address that this will be paired with on the DEX. Fees will be sent to the autoSwapReciever in the base token denomination
constructor(string memory name, string memory symbol,
uint totalSupply_,
uint buyFeePercentage, uint sellFeePercentage, uint p2pFeePercentage,
Expand All @@ -43,6 +65,7 @@ abstract contract UniswapV2FeeToken is ERC20
isFeeActive = true;
}

/// @notice This functions is inherited from OpenZeppelin and implements the transaction fee distribution
function _transfer(
address from,
address to,
Expand Down Expand Up @@ -70,21 +93,47 @@ abstract contract UniswapV2FeeToken is ERC20
super._transfer(from, to, amount);
}

/// @notice Set excemptions for transaction fee payments
/// @param account Address that tax configuration will be affected
/// @param isTaxless_ If set to true the account will not pay transaction fees
/// @custom:internal This function is internal, can be overrided.
function _setTaxless(address account, bool isTaxless_) internal
{
isTaxless[account] = isTaxless_;
}

/// @notice Changes the address that will recieve fees
/// @param feeReceiver_ If set to true the account will not pay transaction fees
/// @custom:internal This function is internal, can be overrided.
function _setFeeReceiver(address feeReceiver_) internal
{
feeReceiver = feeReceiver_;
}

/// @notice Changes the address that will recieve fees
/// @param isFeeActive_ If set to true all transaction fees will not be charged
/// @custom:internal This function is internal, can be overrided.
function _setFeeActive(bool isFeeActive_) internal
{
isFeeActive = isFeeActive_;
}

/// @notice The fee percentage for buy, sell and peer to peer
/// @param buyFeePercentage New buy percentage fee
/// @param sellFeePercentage New sell percentage fee
/// @param p2pFeePercentage New peer to peer percentage fee
/// @custom:internal This function is internal, can be overrided.
function _setFees(uint buyFeePercentage, uint sellFeePercentage, uint p2pFeePercentage) internal
{
fees[0] = buyFeePercentage;
fees[1] = sellFeePercentage;
fees[2] = p2pFeePercentage;
}

/// @notice Changes the router, base token and pair address in case the the liquidity wants to be moved to other DEX or base token
/// @param router_ New router that will be updated
/// @param baseToken_ New base token that will be used
/// @custom:internal This function is internal, can be overrided.
function _setPair(address router_, address baseToken_) internal
{
router = ISwapRouter(router_);
Expand All @@ -95,11 +144,4 @@ abstract contract UniswapV2FeeToken is ERC20
pair = ISwapFactory(router.factory()).createPair(address(this), address(baseToken));
}
}

function _setFees(uint buyFeePercentage, uint sellFeePercentage, uint p2pFeePercentage) internal
{
fees[0] = buyFeePercentage;
fees[1] = sellFeePercentage;
fees[2] = p2pFeePercentage;
}
}
78 changes: 67 additions & 11 deletions contracts/ERC20/UniswapV3FeeToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,49 @@ pragma solidity ^0.8.0;
import "./ERC20.sol";
import "./interfaces/UniswapV3Interfaces.sol";

/// @title ERC20 token that takes fees on buy on Uniswap V3 and on peer to peero and transfer them to the feeReceiver.
/// @author Filosofía Codigo
/// @notice You can use this contract launch your own token or to study the Uniswap V3 ecosystem.
/// @dev Based on top OpenZeppelin contracts but changed balances from private to internal for flexibility
abstract contract UniswapV3FeeToken is ERC20
{
/// @notice List of address that won't pay transaction fees
mapping(address => bool) public isTaxless;
/// @notice Address that will recieve fees taken from each transaction
address public feeReceiver;
/// @notice If set to true, no fees will be taken on any transaction
bool public isFeeActive;
/// @notice Fee percentage token when the token is bought on the Uniswap V3 Pair
uint buyFeePercentage;
/// @notice Fee percentage token when the token is transfered to other address outside of the V3 Pair
uint p2pFeePercentage;
/// @notice Number if fee decimals. Default is 2 so for example 250 means 2.5% in percentage numbers
uint public feeDecimals = 2;
/// @notice Token that will be paired with this token when liquidity is added to the DEX
IERC20 baseToken;
/// @dev 0.01% uniswap v3 pool used to check if the token is being bought or sold
address public pool1;
/// @dev 0.05% uniswap v3 pool used to check if the token is being bought or sold
address public pool2;
/// @dev 0.3% uniswap v3 pool used to check if the token is being bought or sold
address public pool3;
/// @dev 1% uniswap v3 pool used to check if the token is being bought or sold
address public pool4;

/// @notice Uniswap V3 Position Manager used to gather the pool addresses
INonfungiblePositionManager public nonfungiblePositionManager
= INonfungiblePositionManager(0xC36442b4a4522E871399CD717aBDD847Ab11FE88);

/// @notice Contract constructor
/// @dev All percentage numbers are two digit decimals. For example 250 means 2.5%
/// @param name Token Name
/// @param symbol Token Symbol
/// @param totalSupply_ Total supply, all supply will be sent to contract deployer
/// @param buyFeePercentage_ Percent of tokens that will be sent to the feeReciever when token is bought on Uniswap V3
/// @param p2pFeePercentage_ Percent of tokens that will be sent to the feeReciever when token is transfered outside of Uniswap V3
/// @param feeReceiver_ Address that will recieve the fees taken every transaction
/// @param baseTokenAddress Token address that this will be paired with on the DEX. Fees will be sent to the autoSwapReciever in the base token denomination
/// @param rate Initial token value in the form of 1 base token = `rate` tokens
constructor(string memory name, string memory symbol,
uint totalSupply_,
uint buyFeePercentage_, uint p2pFeePercentage_,
Expand Down Expand Up @@ -92,17 +118,18 @@ abstract contract UniswapV3FeeToken is ERC20
isFeeActive = true;
}

/// @notice This functions is inherited from OpenZeppelin and implements the transaction fee distribution
function _transfer(
address from,
address to,
uint256 amount
) internal virtual override {
uint256 feesCollected;
if (!isTaxless[from] && !isTaxless[to]) {
if(isPool(from))
if(_isPool(from))
{
feesCollected = (amount * buyFeePercentage) / (10**(feeDecimals + 2));
}else if(!isPool(to))
}else if(!_isPool(to))
{
feesCollected = (amount * p2pFeePercentage) / (10**(feeDecimals + 2));
}
Expand All @@ -117,19 +144,13 @@ abstract contract UniswapV3FeeToken is ERC20
super._transfer(from, to, amount);
}

function setTaxless(address account, bool value) external onlyOwner {
isTaxless[account] = value;
}

function setFeeActive(bool value) public onlyOwner {
isFeeActive = value;
}

function isPool(address _address) public view returns(bool)
/// @dev Checks if an address is part of the Uniswap V3 pools. This is for internal use.
function _isPool(address _address) internal view returns(bool)
{
return _address == pool1 || _address == pool2 || _address == pool3 || _address == pool4;
}

/// @dev Square root function for internal use
function sqrt(uint y) internal pure returns (uint z) {
if (y > 3) {
z = y;
Expand All @@ -142,4 +163,39 @@ abstract contract UniswapV3FeeToken is ERC20
z = 1;
}
}

/// @notice Set excemptions for transaction fee payments
/// @param account Address that tax configuration will be affected
/// @param isTaxless_ If set to true the account will not pay transaction fees
/// @custom:internal This function is internal, can be overrided.
function _setTaxless(address account, bool isTaxless_) internal
{
isTaxless[account] = isTaxless_;
}

/// @notice Changes the address that will recieve fees
/// @param feeReceiver_ If set to true the account will not pay transaction fees
/// @custom:internal This function is internal, can be overrided.
function _setFeeReceiver(address feeReceiver_) internal
{
feeReceiver = feeReceiver_;
}

/// @notice Changes the address that will recieve fees
/// @param isFeeActive_ If set to true all transaction fees will not be charged
/// @custom:internal This function is internal, can be overrided.
function _setFeeActive(bool isFeeActive_) internal
{
isFeeActive = isFeeActive_;
}

/// @notice The fee percentage for buy, sell and peer to peer
/// @param buyFeePercentage_ New buy percentage fee
/// @param p2pFeePercentage_ New peer to peer percentage fee
/// @custom:internal This function is internal, can be overrided.
function _setFees(uint buyFeePercentage_, uint p2pFeePercentage_) internal
{
buyFeePercentage = buyFeePercentage_;
p2pFeePercentage = p2pFeePercentage_;
}
}
Loading

0 comments on commit 2edd9e7

Please sign in to comment.