Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Custom oracle in USDTieredSTO #691

Merged
merged 2 commits into from
Jun 13, 2019
Merged
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
24 changes: 21 additions & 3 deletions contracts/modules/STO/USDTiered/USDTieredSTO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,23 @@ contract USDTieredSTO is USDTieredSTOStorage, STO {
_modifyAddresses(_wallet, _treasuryWallet, _usdTokens);
}

/**
* @dev Modifies Oracle address.
* By default, Polymath oracles are used but issuer can overide them using this function
* Set _oracleAddress to 0x0 to fallback to using Polymath oracles
* @param _fundRaiseType Actual currency
* @param _oracleAddress address of the oracle
*/
function modifyOracle(FundRaiseType _fundRaiseType, address _oracleAddress) external {
_onlySecurityTokenOwner();
if (_fundRaiseType == FundRaiseType.ETH) {
customOracles[bytes32("ETH")][bytes32("USD")] = _oracleAddress;
} else {
require(_fundRaiseType == FundRaiseType.POLY, "Invalid currency");
customOracles[bytes32("POLY")][bytes32("USD")] = _oracleAddress;
}
}

function _modifyLimits(uint256 _nonAccreditedLimitUSD, uint256 _minimumInvestmentUSD) internal {
minimumInvestmentUSD = _minimumInvestmentUSD;
nonAccreditedLimitUSD = _nonAccreditedLimitUSD;
Expand Down Expand Up @@ -757,8 +774,9 @@ contract USDTieredSTO is USDTieredSTOStorage, STO {
return this.configure.selector;
}

function _getOracle(bytes32 _currency, bytes32 _denominatedCurrency) internal view returns(address) {
return IPolymathRegistry(ISecurityToken(securityToken).polymathRegistry()).getAddress(oracleKeys[_currency][_denominatedCurrency]);
function _getOracle(bytes32 _currency, bytes32 _denominatedCurrency) internal view returns(address oracleAddress) {
oracleAddress = customOracles[_currency][_denominatedCurrency];
if (oracleAddress == address(0))
oracleAddress = IPolymathRegistry(ISecurityToken(securityToken).polymathRegistry()).getAddress(oracleKeys[_currency][_denominatedCurrency]);
}

}
2 changes: 2 additions & 0 deletions contracts/modules/STO/USDTiered/USDTieredSTOStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,6 @@ contract USDTieredSTOStorage {
// Array of Tiers
Tier[] public tiers;

// Optional custom Oracles.
mapping(bytes32 => mapping(bytes32 => address)) customOracles;
}
36 changes: 36 additions & 0 deletions test/p_usd_tiered_sto.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ contract("USDTieredSTO", async (accounts) => {
let ETH = 0;
let POLY = 1;
let DAI = 2;
let oldEthRate;
let oldPolyRate;

let MESSAGE = "Transaction Should Fail!";
const GAS_PRICE = 0;
Expand Down Expand Up @@ -909,6 +911,40 @@ contract("USDTieredSTO", async (accounts) => {
});

describe("Test modifying configuration", async () => {
it("Should not allow unauthorized address to change oracle address", async () => {
let stoId = 3;
await catchRevert(I_USDTieredSTO_Array[stoId].modifyOracle(ETH, address_zero, { from: ACCREDITED1 }));
});

it("Should not allow to change oracle address for currencies other than ETH and POLY", async () => {
let stoId = 3;
await catchRevert(I_USDTieredSTO_Array[stoId].modifyOracle(DAI, address_zero, { from: ISSUER }));
});

it("Should allow to change oracle address for ETH", async () => {
let stoId = 3;
oldEthRate = await I_USDTieredSTO_Array[stoId].getRate.call(ETH);
let I_USDOracle2 = await MockOracle.new(address_zero, web3.utils.fromAscii("ETH"), web3.utils.fromAscii("USD"), e18, { from: POLYMATH });
await I_USDTieredSTO_Array[stoId].modifyOracle(ETH, I_USDOracle2.address, { from: ISSUER });
assert.equal((await I_USDTieredSTO_Array[stoId].getRate.call(ETH)).toString(), e18.toString());
});

it("Should allow to change oracle address for POLY", async () => {
let stoId = 3;
oldPolyRate = await I_USDTieredSTO_Array[stoId].getRate.call(POLY);
let I_POLYOracle2 = await MockOracle.new(I_PolyToken.address, web3.utils.fromAscii("POLY"), web3.utils.fromAscii("USD"), e18, { from: POLYMATH });
await I_USDTieredSTO_Array[stoId].modifyOracle(POLY, I_POLYOracle2.address, { from: ISSUER });
assert.equal((await I_USDTieredSTO_Array[stoId].getRate.call(POLY)).toString(), e18.toString());
});

it("Should use official oracles when custom oracle is set to 0x0", async () => {
let stoId = 3;
await I_USDTieredSTO_Array[stoId].modifyOracle(ETH, address_zero, { from: ISSUER });
await I_USDTieredSTO_Array[stoId].modifyOracle(POLY, address_zero, { from: ISSUER });
assert.equal((await I_USDTieredSTO_Array[stoId].getRate.call(ETH)).toString(), oldEthRate.toString());
assert.equal((await I_USDTieredSTO_Array[stoId].getRate.call(POLY)).toString(), oldPolyRate.toString());
});

it("Should successfully change config before startTime - funding", async () => {
let stoId = 3;
await I_USDTieredSTO_Array[stoId].modifyFunding([0], { from: ISSUER });
Expand Down