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

Fix ci build #451

Merged
merged 18 commits into from
Jan 20, 2022
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
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