Skip to content
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
3 changes: 2 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ jobs:
MAINNET_PK: ${{ secrets.TESTNET }}
TESTNET_PK: ${{ secrets.TESTNET }}
ETHERSCAN_API_KEY: none
COINMARKETCAP_API_KEY: none
COINMARKETCAP_API_KEY: none
ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"solidity.compileUsingRemoteVersion": "v0.7.6+commit.7338295f"
}
54 changes: 54 additions & 0 deletions contracts/_chainlink/interfaces/AggregatorV3Interface.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

interface AggregatorV3Interface {

function decimals()
external
view
returns (
uint8
);

function description()
external
view
returns (
string memory
);

function version()
external
view
returns (
uint256
);

// getRoundData and latestRoundData should both raise "No data present"
// if they do not have data to report, instead of returning unset values
// which could be misinterpreted as actual reported values.
function getRoundData(
uint80 _roundId
)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);

function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);

}
76 changes: 76 additions & 0 deletions contracts/oracle/renFil/RenFILOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.7.6;

import "../../oracle/OracleCommon.sol";
import "../../interface/IERC20Extended.sol";
import "../../_chainlink/interfaces/AggregatorV3Interface.sol";
import "../../_openzeppelin/math/SafeMath.sol";

/**
@notice renFIL/USD ChainLink Oracle
*/

contract RenFILOracle is OracleCommon {

using SafeMath for uint256;

uint private constant SHIFT_DECIMALS = 10 ** 10;
AggregatorV3Interface internal priceFeed;

/**
@param oneTokenFactory_ oneToken factory to bind to
@param description_ description has no bearing on logic
@param indexToken_ token to use for price quotes
*/
constructor(address oneTokenFactory_, string memory description_, address indexToken_, address chainlink_)
OracleCommon(oneTokenFactory_, description_, indexToken_) {
priceFeed = AggregatorV3Interface(chainlink_);
}

/**
@notice update is called when a oneToken wants to persist observations
@dev there is nothing to do in this case
*/
function update(address /* token */) external override {}

/**
@notice returns equivalent amount of index tokens for an amount of baseTokens and volatility metric
// param address unused token address
@param amountTokens quantity, token native precision
@param amountUsd US dollar equivalentm, precision 18
@param volatility metric for future use-cases
*/
function read(address /* token */, uint256 amountTokens) public view override returns(uint256 amountUsd, uint256 volatility) {
amountUsd = (amountTokens.mul(getThePrice())).div(PRECISION);
volatility = 1;
}

/**
@notice returns the tokens needed to reach a target usd value
// param address unused token address
@param amountUsd Usd required, precision 18
@param amountTokens tokens required, token native precision
@param volatility metric for future use-cases
*/
function amountRequired(address /* token */, uint256 amountUsd) external view override returns(uint256 amountTokens, uint256 volatility) {
amountTokens = amountUsd.mul(PRECISION).div(getThePrice());
volatility = 1;
}

/**
* Returns the latest price
*/
function getThePrice() public view returns (uint256 price) {
(
,
int256 price_,
,
,

) = priceFeed.latestRoundData();
require(price_ > 0); // price oracle responded 0, or negative. No event emitted because this is a view function.
price = uint256(price_);
price = price.mul(SHIFT_DECIMALS); //price is natively in 8 decimals make it 18
}
}
20 changes: 20 additions & 0 deletions contracts/testToken/memberTokens/renFILMockToken.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.7.6;

import "../../oz_modified/ICHIERC20.sol";
import "../../_openzeppelin/access/Ownable.sol";

contract RenFILMockToken is ICHIERC20, Ownable {

constructor() {
initERC20("renFIL","renFIL");
_mint(msg.sender, 10000 * 10 ** 18);

}

function mint(address _to, uint256 _amount) public onlyOwner {
_mint(_to, _amount);
}

}
2 changes: 1 addition & 1 deletion deploy/mintMasterIncrementalVerify.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module.exports = async function({ ethers: { getNamedSigner }, getNamedAccounts,
factory = await deployments.get("OneTokenFactory")
mintMaster = await deployments.get("Incremental")

if (chainId != 31337) { //don't verify contract on localnet
if (chainId == 42 || chainId == 1) { //don't verify contract on localnet
await hre.run("verify:verify", {
address: mintMaster.address,
constructorArguments: [
Expand Down
2 changes: 1 addition & 1 deletion deploy/nullControllerVerify.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = async function({ ethers: { getNamedSigner }, getNamedAccounts,
factory = await deployments.get("OneTokenFactory")
controller = await deployments.get("NullController")

if (chainId != 31337) { //don't verify contract on localnet
if (chainId == 42 || chainId == 1) { //don't verify contract on localnet
await hre.run("verify:verify", {
address: controller.address,
constructorArguments: [
Expand Down
18 changes: 18 additions & 0 deletions deploy/oneTokenDeploys/renFIL.mocktoken.kovan.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = async function({ ethers: { getNamedSigner }, getNamedAccounts, deployments }) {
const { deploy } = deployments

const { deployer, dev } = await getNamedAccounts()

const chainId = await getChainId()

if (chainId == 42) { //don't deploy to mainnet
await deploy("RenFILMockToken", {
from: deployer,
log: true
})
}


}

module.exports.tags = ["renFILMockToken"]
120 changes: 120 additions & 0 deletions deploy/oneTokenDeploys/renFIL.oneFIL.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// example deploy of a oneToken from the factory

module.exports = async function({ ethers: { getNamedSigner }, getNamedAccounts, deployments }) {
const { deploy } = deployments

const { deployer, dev } = await getNamedAccounts()

const chainId = await getChainId()

const moduleType = {
version: 0,
controller: 1,
strategy: 2,
mintMaster: 3,
oracle: 4,
voterRoll: 5
}

const
name = "oneFIL"
url = "ichi.org"
symbol = "oneFIL",
versionName = "OneTokenV1"

let collateralTokenAddress,
memberTokenAddress,
controllerAddress,
mintMasterAddress,
oneTokenOracleAddress,
memberOracleAddress,
oneTokenV1Address,
governaceAddress


if (chainId == 42) {

const memberToken = await deployments.get("RenFILMockToken")
memberTokenAddress = memberToken.address

collateralTokenAddress = '0x21632981cBf52eB788171e8dcB891C32F4834239'

const memberOracle = await deployments.get("RenFILOracle")
memberOracleAddress = memberOracle.address


const oneTokenV1 = await deployments.get("OneTokenV1")
oneTokenV1Address = oneTokenV1.address

const controllerNull = await deployments.get("NullController")
controllerAddress = controllerNull.address

const mintMasterIncremental = await deployments.get("Incremental")
mintMasterAddress = mintMasterIncremental.address

const oneTokenOracle = await deployments.get("ICHIPeggedOracle")
oneTokenOracleAddress = oneTokenOracle.address

governaceAddress = '0x451Efff92a3a1471b7af9DDc1369D9D157E6475A'





} else if (chainId == 1) {

memberTokenAddress = '0xD5147bc8e386d91Cc5DBE72099DAC6C9b99276F5'

collateralTokenAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'

const memberOracle = await deployments.get("RenFILOracle")
memberOracleAddress = memberOracle.address


const oneTokenV1 = await deployments.get("OneTokenV1")
oneTokenV1Address = oneTokenV1.address

const controllerNull = await deployments.get("NullController")
controllerAddress = controllerNull.address

const mintMasterIncremental = await deployments.get("Incremental")
mintMasterAddress = mintMasterIncremental.address

const oneTokenOracle = await deployments.get("ICHIPeggedOracle")
oneTokenOracleAddress = oneTokenOracle.address

governaceAddress = '0x321e897eb342AE8a92310fa9BAD4de9d3140a8bb'
}

console.log('*************************************************************')
console.log('admit memberToken: admitForeignToken')
console.log('foreignToken (address): ',memberTokenAddress)
console.log('collateral (bool): false')
console.log('oracle (address): ',memberOracleAddress)
console.log('*************************************************************')

console.log('*************************************************************')
console.log('admit collateralToken: admitForeignToken')
console.log('foreignToken (address): ',)
console.log('collateral (bool): true')
console.log('oracle (address): ',)
console.log('*************************************************************')


console.log('*************************************************************')
console.log('deployOneTokenProxy: ')
console.log('name (string): ',name)
console.log('symbol (string): ',symbol)
console.log('governance (address): ',governaceAddress)
console.log('version (address): ',oneTokenV1Address)
console.log('controller (address): ',controllerAddress)
console.log('mintMaster (address): ',mintMasterAddress)
console.log('oneTokenOracle (address): ',oneTokenOracleAddress)
console.log('memberToken (address): ',memberTokenAddress)
console.log('collateral (address): ',collateralTokenAddress)

console.log('*************************************************************')
}

module.exports.tags = ["oneFIL",]
//module.exports.dependencies = ["oneTokenFactory","nullController","mintMasterIncremental","renFILOracle"]
67 changes: 67 additions & 0 deletions deploy/oneTokenDeploys/renFIL.oracle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const { factory } = require("typescript")

module.exports = async function({ ethers: { getNamedSigner }, getNamedAccounts, deployments }) {
const { deploy } = deployments

const { deployer, dev } = await getNamedAccounts()

const chainId = await getChainId()

const moduleType = {
version: 0,
controller: 1,
strategy: 2,
mintMaster: 3,
oracle: 4,
voterRoll: 5
}

const
name = 'renFIL/USD Oracle',
url = 'https://data.chain.link/ethereum/mainnet/crypto-usd/fil-usd'

let token,
admin,
oracle

if (chainId == 42) {
token = await deployments.get('RenFILMockToken')
const factory = await deployments.get("OneTokenFactory")
const Admin = await ethers.getContractFactory("OneTokenFactory")
admin = Admin.attach(factory.address)

oracle = await deploy('RenFILOracle', {
from: deployer,
args: [factory.address, name, token.address, '0xDA5904BdBfB4EF12a3955aEcA103F51dc87c7C39'], //this points to uni chainlink oracle on kovan since FIL doesn't exist on kovan
log: true
})
await admin.admitModule(oracle.address, moduleType.oracle, name, url, {
from: deployer
})
} else if (chainId == 1) {
const tokenAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' //usdc indextoken
const factory = await deployments.get("OneTokenFactory")
const chainlinkAddress = '0x1A31D42149e82Eb99777f903C08A2E41A00085d3'


oracle = await deploy('RenFILOracle', {
from: deployer,
args: [factory.address, name, tokenAddress, chainlinkAddress],
log: true
})
console.log('*************************************************************')
console.log('admitModule')
console.log('module (address): ',oracle.address)
console.log('moduleType (uint8): ',moduleType.oracle)
console.log('name (string): ',name)
console.log('url (string): ',url)
console.log('*************************************************************')
}




}

module.exports.tags = ["renFILOracle"]
module.exports.dependencies = ["renFILMockToken","oneTokenFactory"]
Loading