-
Notifications
You must be signed in to change notification settings - Fork 153
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
Deploy and proposal for USDT market on Goerli #801
base: main
Are you sure you want to change the base?
Conversation
The scenario will fail as we encountered back in Arbitrum native usdc deploy. But this can be confirmed in migration PR, which with migration script the scenario run will succeed. |
120fe1e
to
e791775
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
···································|··············|·················
| CometFactory · 24.044 · │
···································|··············|·················
| CometModifiedFactory · 24.182 · │
···································|··············|·················
The contract size is approaching to limit, compiler will complain with Warning: 2 contracts exceed the size limit for mainnet deployment.
But the actual size limit is 24.576 kb, so we should be fine :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Could you also add unit tests for supply base
, supply collateral
, and buy collateral
? I notice there is no scenarios for buy collateral
, so would be good to get some unit test coverage at least.
Co-authored-by: Kevin Cheng <[email protected]>
Co-authored-by: Kevin Cheng <[email protected]>
Co-authored-by: Kevin Cheng <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work on the tests! They look great 👍
Co-authored-by: Kevin Cheng <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think this should be ready for audit with OZ now!
Could you update the PR description to say this introduces a new implementation of Comet that supports non-standard ERC20s and fee tokens?
Separately, I wonder if we should add this logic in a new Comet
file, like NonStandardComet
or FeeTokenComet
?
…h new Comet logics that will compare Comet's raw balance diff to credit user in accounting. Comet's always got 0 token, so comet always credit 0, thus it won't hit SupplyCapExceeded() error no more
Looking at the re-entrancy test fixes, I think the better fix is actually just to have the |
…dded one test case to show the known vulnerability (re-entrance when token contract itself is eploited)
Synced with ⛑️ offline. For reference, if import re-entrancy guard from openzeppelin which can prevent exploited token contract to execute re-entrancy attack, but it will also increase the contract size to:
|
test/supply-test.ts
Outdated
).to.be.revertedWith("custom error 'SupplyCapExceeded()'"); | ||
).to.be.revertedWith("custom error 'TransferInFailed()'"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now the accounting in comet won't be inflated by re-entrancy supply reaching SupplyCapExceeded().
It will be blocked and throw TransferInFailed() error.
test/withdraw-test.ts
Outdated
).to.be.revertedWith("custom error 'NotCollateralized()'"); | ||
).to.be.revertedWith("custom error 'TransferOutFailed()'"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now the accounting in comet won't be mistaken by re-entrancy withdraw reaching NotColalteralized() error.
Instead, it will be blocked and throw TransferInFailed() error right away.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't it throw the re-entrancy error instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it was bit weird, but since the error is thrown in the nested transfer() function, so it gets sort of "re-wrap" into TransferInFailed() as the code here doesn't re-raise the error (or should we make it re-raise the error?)
uint256 preTransferBalance = ERC20(asset).balanceOf(address(this));
(bool success, bytes memory returndata) = asset.call(abi.encodeWithSelector(ERC20.transferFrom.selector, from, address(this), amount));
if (!success || !(returndata.length == 0 || abi.decode(returndata, (bool)))) {
revert TransferInFailed();
}
return ERC20(asset).balanceOf(address(this)) - preTransferBalance;
From code we can see now the transferFrom revert won't reveirt right away with returndata, but instead when it fails, we throw TransferInFailed()
.
contracts/CometCore.sol
Outdated
/// @dev The reentrancy guard status | ||
uint256 internal constant COMET_REENTRANCY_GUARD_NOT_ENTERED = 1; | ||
uint256 internal constant COMET_REENTRANCY_GUARD_ENTERED = 2; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can just inline rather than creating constants. Also, let's use a default value of 0. Otherwise, you need to initialize the slot to 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recalled seeing in openzeppelin's reentrancy guard contract saying that using 1, 2 is cheaper on running than setting it to 0. (reference: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/ReentrancyGuard.sol)
Since we're only checking on if status == COMET_REENTRANCY_GUARD_ENTERED. It looks like the initialization value of 0 or 1 wouldn't affect the first run behavior, so I ended up changing to 1,2. And each run it only checks on if the status is ENTERED(2) :P. But yeah I agree the first initialization value having to be 0 instead of 1 is a bit confusing, and I can change it back to 0 if the gas saving gain is not enough to tradeoff with the confusion initialization values.
contracts/Comet.sol
Outdated
@@ -776,7 +802,7 @@ contract Comet is CometMainInterface { | |||
* @dev Safe ERC20 transfer out | |||
* @dev Note: Safely handles non-standard ERC-20 tokens that do not return a value. See here: https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca | |||
*/ | |||
function doTransferOut(address asset, address to, uint amount) internal { | |||
function doTransferOut(address asset, address to, uint amount) nonReentrant internal { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having nonReentrant
on the transfer functions breaks BuyCollateral
right?
// EvilToken attack is using 3000 EVIL tokens, so totalSupplyBase should have 3000e6 | ||
expect(evilTotalsBasic.totalSupplyBase).to.equal(3000e6); | ||
// EvilToken attack should be blocked | ||
expect(evilTotalsBasic.totalSupplyBase).to.equal(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add an assertion to assert the re-entrancy error.
test/withdraw-test.ts
Outdated
@@ -558,7 +558,7 @@ describe('withdraw', function () { | |||
// in callback, EvilToken attempts to withdraw USDC to bob's address | |||
await expect( | |||
comet.connect(alice).withdraw(EVIL.address, 1e6) | |||
).to.be.revertedWith("custom error 'NotCollateralized()'"); | |||
).to.be.revertedWith("custom error 'TransferOutFailed()'"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test name should change as well
test/withdraw-test.ts
Outdated
).to.be.revertedWith("custom error 'NotCollateralized()'"); | ||
).to.be.revertedWith("custom error 'TransferOutFailed()'"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't it throw the re-entrancy error instead?
85be018
to
a13050a
Compare
Address oz's feedback on USDT comet support
This PR introduces the deployment for USDT Goerli as well as the proposal to initialize the market there.
For ease of managing the changes the initialize proposal and migration scripts changes are in: PR#802, which will be merged later on.
Comet Contract changes in this PR:
doTransferIn
anddoTransferOut
to support non-standard erc20,doTransferIn
to return actual transferred amount for better accounting in non-standard erc20 and fee token scenariossupplyBase
,supplyCollateral
,buyCollateral
to account the actual transferred values returned bydoTransferIn
TODO: