84 lines
3.0 KiB
Solidity
84 lines
3.0 KiB
Solidity
|
// SPDX-License-Identifier: MIT
|
||
|
pragma solidity ^0.6.12;
|
||
|
pragma experimental ABIEncoderV2;
|
||
|
|
||
|
import { FeeManager, IERC20, ITornadoInstance, UniswapV3OracleHelper } from "../FeeManager.sol";
|
||
|
import { OwnableLibrary } from "../libraries/OwnableLibrary.sol";
|
||
|
|
||
|
/**
|
||
|
* @dev Stores and returns overrided TORN-Token price
|
||
|
Literally you don't need to do this unless you don't want to occupy another storage slot for the contract
|
||
|
*/
|
||
|
library TokenPriceLibrary {
|
||
|
struct PriceStorage {
|
||
|
mapping(address => uint256) _prices;
|
||
|
}
|
||
|
|
||
|
bytes32 private constant PriceStorageLocation = keccak256(abi.encode(uint256(keccak256("tornado.storage.price"))));
|
||
|
|
||
|
function _getPriceStorage() private pure returns (PriceStorage storage pointer) {
|
||
|
bytes32 slot = PriceStorageLocation;
|
||
|
assembly {
|
||
|
pointer_slot := slot
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function setPrice(address _token, uint256 _price) internal {
|
||
|
PriceStorage storage priceStorage = _getPriceStorage();
|
||
|
priceStorage._prices[_token] = _price;
|
||
|
}
|
||
|
|
||
|
function getPrice(address _token) internal view returns (uint256 price) {
|
||
|
PriceStorage storage priceStorage = _getPriceStorage();
|
||
|
price = priceStorage._prices[_token];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev A testnet feeManager that the maintainer could override V3 oracles, assuming it has been deployed with TestnetProxy
|
||
|
*/
|
||
|
contract TestnetFeeManager is FeeManager {
|
||
|
constructor(
|
||
|
address _torn,
|
||
|
address _governance,
|
||
|
address _registry
|
||
|
) public FeeManager(_torn, _governance, _registry) {}
|
||
|
|
||
|
modifier onlyOwner {
|
||
|
require(OwnableLibrary.getOwner() == msg.sender, "Not an owner");
|
||
|
_;
|
||
|
}
|
||
|
|
||
|
function setTokenPrice(address _token, uint256 _price) external onlyOwner {
|
||
|
TokenPriceLibrary.setPrice(_token, _price);
|
||
|
}
|
||
|
|
||
|
function getTokenPriceRatio(address _token, uint24 _uniswapPoolSwappingFee) public view returns (uint256) {
|
||
|
return TokenPriceLibrary.getPrice(_token) != 0
|
||
|
? TokenPriceLibrary.getPrice(_token)
|
||
|
: UniswapV3OracleHelper.getPriceRatioOfTokens(
|
||
|
[torn, _token],
|
||
|
[uniswapTornPoolSwappingFee, _uniswapPoolSwappingFee],
|
||
|
uniswapTimePeriod
|
||
|
);
|
||
|
}
|
||
|
|
||
|
function calculatePoolFee(ITornadoInstance _instance) public override view returns (uint160) {
|
||
|
(bool isERC20, IERC20 token, , uint24 uniswapPoolSwappingFee, uint32 protocolFeePercentage) = registry.instances(_instance);
|
||
|
if (protocolFeePercentage == 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
token = token == IERC20(0) && !isERC20 ? IERC20(UniswapV3OracleHelper.WETH) : token; // for eth instances
|
||
|
uint256 tokenPriceRatio = getTokenPriceRatio(address(token), uniswapPoolSwappingFee);
|
||
|
|
||
|
return uint160(
|
||
|
_instance
|
||
|
.denomination()
|
||
|
.mul(UniswapV3OracleHelper.RATIO_DIVIDER)
|
||
|
.div(tokenPriceRatio)
|
||
|
.mul(uint256(protocolFeePercentage))
|
||
|
.div(PROTOCOL_FEE_DIVIDER)
|
||
|
);
|
||
|
}
|
||
|
}
|