Skip to content

Commit

Permalink
Fix ci build (#451)
Browse files Browse the repository at this point in the history
* allow anyone to be able to set prices

* test round id is not too early or too late

* fix integration test

* fix comments

* update eth-sig-util package

* remove eth-sig-utils

* update readme for deployments of pricers

* modify package.json

* lint fixes

* init

* Update truffle-config.js

* Update package-lock.json

* Update package-lock.json

* Update package-lock.json

* Added tolerance for failing tests

Co-authored-by: aparnakr <[email protected]>
  • Loading branch information
DemolaJames and aparnakr authored Jan 20, 2022
1 parent a28ead5 commit bb08168
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 44 deletions.
32 changes: 21 additions & 11 deletions contracts/pricers/ChainlinkPricer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,35 @@ contract ChainLinkPricer is OpynPricerInterface {
aggregatorDecimals = uint256(aggregator.decimals());
}

/**
* @notice modifier to check if sender address is equal to bot address
*/
modifier onlyBot() {
require(msg.sender == bot, "ChainLinkPricer: unauthorized sender");

_;
}

/**
* @notice set the expiry price in the oracle, can only be called by Bot address
* @dev a roundId must be provided to confirm price validity, which is the first Chainlink price provided after the expiryTimestamp
* @param _expiryTimestamp expiry to set a price for
* @param _roundId the first roundId after expiryTimestamp
*/
function setExpiryPriceInOracle(uint256 _expiryTimestamp, uint80 _roundId) external onlyBot {
function setExpiryPriceInOracle(uint256 _expiryTimestamp, uint80 _roundId) external {
(, int256 price, , uint256 roundTimestamp, ) = aggregator.getRoundData(_roundId);

require(_expiryTimestamp <= roundTimestamp, "ChainLinkPricer: invalid roundId");
require(_expiryTimestamp <= roundTimestamp, "ChainLinkPricer: roundId not first after expiry");
require(price >= 0, "ChainLinkPricer: invalid price");

if (msg.sender != bot) {
bool isCorrectRoundId;
uint80 previousRoundId = uint80(uint256(_roundId).sub(1));

while (!isCorrectRoundId) {
(, , , uint256 previousRoundTimestamp, ) = aggregator.getRoundData(previousRoundId);

if (previousRoundTimestamp == 0) {
require(previousRoundId > 0, "ChainLinkPricer: Invalid previousRoundId");
previousRoundId = previousRoundId - 1;
} else if (previousRoundTimestamp > _expiryTimestamp) {
revert("ChainLinkPricer: previousRoundId not last before expiry");
} else {
isCorrectRoundId = true;
}
}
}

oracle.setExpiryPrice(asset, _expiryTimestamp, uint256(price));
}
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,15 @@
},
"dependencies": {
"@truffle/hdwallet-provider": "^1.6.0",
"eth-sig-util": "^3.0.1",
"solc-0.6.10": "npm:[email protected]",
"solidity-docgen": "^0.5.6",
"yargs": "^13.2.4"
},
"devDependencies": {
"@0x/protocol-utils": "^1.4.0",
"@codechecks/client": "^0.1.10",
"@metamask/eth-sig-util": "^4.0.0",
"@openzeppelin/cli": "^2.8.2",
"@openzeppelin/test-helpers": "^0.5.4",
"@types/chai": "4.2.5",
Expand All @@ -111,7 +113,6 @@
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-prettier": "^3.1.1",
"eth-gas-reporter": "^0.2.17",
"eth-sig-util": "^3.0.0",
"ethereumjs-util": "^7.0.7",
"ethereumjs-wallet": "^1.0.1",
"ethers": "^5.0.26",
Expand Down
7 changes: 6 additions & 1 deletion scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ To deploy a new `ChainlinkPricer.sol`, it is recommended to use the `deployChain
**Input**

```sh
truffle exec scripts/deployChainlinkPricer.js --network mainnet --controller 0x7d78c401c69c56cb21f4bf80c53afd92be0BBBBB --pool 0xc02aaa39b223fe8d0a0e5c4f27ead9083c7AAaaa --weth 0x5f4eC3Df9cbd43714FE2740f5E3616155cAGAGAG --oracle 0xef196aA0e3Cb8EA6d5720557C3B611Eff6OOOOOO --gasPrice 50000000000
truffle exec scripts/deployChainlinkPricer.js --network mainnet --bot 0xfacb407914655562d6619b0048a612B1795dF783 --asset 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599 --aggregator 0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c --oracle 0x789cD7AB3742e23Ce0952F6Bc3Eb3A73A0E08833 --gasPrice 100000000000
```

**Output**
Expand Down Expand Up @@ -105,3 +105,8 @@ Mock pricer deployed! 🎉
Transaction hash: 0xebf12fc6603ee857bcabe1c0c6194XX82639a9888776f7ff6e83a409XXXXXXXX
Deployed contract address: 0x669cC97687c792fc5369d7bdd38cXXXXXXXXXX
```

## Verification of Contracts
```sh
truffle run verify ChainlinkPricer@0x17FDF6cE88517bf0Cff19e014E509B543DD78432 --network mainnet
```
19 changes: 13 additions & 6 deletions test/integration-tests/nakedMarginPutPreExpiry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -659,9 +659,11 @@ contract('Naked margin: put position pre expiry', ([owner, accountOwner1, buyer1
'Liquidator collateral balance mismatch after liquidation',
)

assert.equal(
poolUsdcAfter.plus(isLiquidatable[1].toString()).minus(collateralToDeposit.toString()).toString(),
poolUsdcBefore.toString(),
assert.isAtMost(
calcRelativeDiff(poolUsdcAfter.plus(isLiquidatable[1]).minus(collateralToDeposit), poolUsdcBefore)
.dividedBy(new BigNumber(10 ** usdcDecimals))
.toNumber(),
new BigNumber(errorDelta).toNumber(),
'Pool balance after openining position mismatch',
)

Expand All @@ -686,9 +688,14 @@ contract('Naked margin: put position pre expiry', ([owner, accountOwner1, buyer1
createTokenAmount(0),
'Liquidator vault short amount mismatch',
)
assert.equal(
new BigNumber(userVaultAfter[0].collateralAmounts[0]).toString(),
new BigNumber(userVaultBefore[0].collateralAmounts[0]).minus(new BigNumber(isLiquidatable[1])).toString(),
assert.isAtMost(
calcRelativeDiff(
new BigNumber(userVaultAfter[0].collateralAmounts[0]),
new BigNumber(userVaultBefore[0].collateralAmounts[0]).minus(new BigNumber(isLiquidatable[1])),
)
.dividedBy(new BigNumber(10 ** usdcDecimals))
.toNumber(),
new BigNumber(errorDelta).toNumber(),
'User vault short amount mismatch after liquidation',
)
})
Expand Down
12 changes: 0 additions & 12 deletions test/integration-tests/pricer-oracle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,18 +162,6 @@ contract('Pricer + Oracle', ([owner, bot, disputer, random]) => {
)
})

it('should revert set weth price if sender is not bot address', async () => {
const expiryTimestamp = (t0 + t1) / 2 // between t0 and t1
if ((await time.latest()) < expiryTimestamp + lockingPeriod) {
await time.increaseTo(expiryTimestamp + lockingPeriod + 10)
}
const roundId = 1
await expectRevert(
wethPricer.setExpiryPriceInOracle(expiryTimestamp, roundId, { from: random }),
'ChainLinkPricer: unauthorized sender',
)
})

it('should set weth price when sender is bot address', async () => {
const expiryTimestamp = (t0 + t1) / 2 // between t0 and t1
if ((await time.latest()) < expiryTimestamp + lockingPeriod) {
Expand Down
31 changes: 24 additions & 7 deletions test/unit-tests/chainlinkPricer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ contract('ChainlinkPricer', ([owner, bot, random]) => {
await wethAggregator.setRoundTimestamp(4, t4)
})

it('should set the correct price to the oracle', async () => {
it('bot should set the correct price to the oracle', async () => {
const expiryTimestamp = (t0 + t1) / 2 // between t0 and t1
const roundId = 1

Expand All @@ -128,21 +128,38 @@ contract('ChainlinkPricer', ([owner, bot, random]) => {
assert.equal(p1.toString(), priceFromOracle[0].toString())
})

it('should revert if sender is not bot address', async () => {
const expiryTimestamp = (t1 + t2) / 2 // between t0 and t1
it('should revert if sender is not bot address and roundId is too old', async () => {
const expiryTimestamp = (t1 + t2) / 2 // between t1 and t2
const roundId = 1
await expectRevert(
pricer.setExpiryPriceInOracle(expiryTimestamp, roundId, { from: random }),
'ChainLinkPricer: unauthorized sender',
'ChainLinkPricer: roundId not first after expiry',
)
})

it('should revert if round ID is incorrect: price[roundId].timestamp < expiry', async () => {
const expiryTimestamp = (t1 + t2) / 2 // between t0 and t1
it('should revert if sender is not bot address and roundId is too late', async () => {
const expiryTimestamp = (t1 + t2) / 2 // between t1 and t2
const roundId = 3
await expectRevert(
pricer.setExpiryPriceInOracle(expiryTimestamp, roundId, { from: random }),
'ChainLinkPricer: previousRoundId not last before expiry',
)
})

it('anyone should be able to set prices', async () => {
const expiryTimestamp = (t1 + t2) / 2 // between t1 and t2
const roundId = 2
await pricer.setExpiryPriceInOracle(expiryTimestamp, roundId, { from: random })
const priceFromOracle = await oracle.getExpiryPrice(weth.address, expiryTimestamp)
assert.equal(p2.toString(), priceFromOracle[0].toString())
})

it('should revert if round ID is too late: price[roundId].timestamp < expiry', async () => {
const expiryTimestamp = (t1 + t2) / 2 // between t1 and t2
const roundId = 1
await expectRevert(
pricer.setExpiryPriceInOracle(expiryTimestamp, roundId, { from: bot }),
'ChainLinkPricer: invalid roundId',
'ChainLinkPricer: roundId not first after expiry',
)
})
})
Expand Down
7 changes: 2 additions & 5 deletions test/unit-tests/liquidations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,8 @@ contract('MarginCalculator: liquidation', ([owner, random]) => {
)

assert.equal(isLiquidatable[0], true, 'isLiquidatable boolean value mismatch')
assert.equal(
new BigNumber(isLiquidatable[1].toString()).toString(),
new BigNumber(expectedLiquidationPrice).toString(),
'debt price value mismatch',
)

assert.equal(new BigNumber(isLiquidatable[1]).toNumber(), expectedLiquidationPrice, 'debt price value mismatch')
assert.equal(isLiquidatable[2].toString(), usdcDust, 'collateral dust value mismatch')
})

Expand Down

0 comments on commit bb08168

Please sign in to comment.