opynfinance / convexityprotocol Goto Github PK
View Code? Open in Web Editor NEWLicense: Other
License: Other
https://www.figma.com/file/eQhRGVDQcoRTd5455V8FvA/Integration-Tests?node-id=0%3A1
Refer to Test Exercise + Claim Collateral
OptionsContract.transferUnderlying(address,uint256) ignores return value by underlying.transfer(_addr,_amt)
Ensure that all the return values of the function calls are used.
Should check if option collateral is an ERC20 and not ETH when calling addERC20Collateral()
OptionsContract.isSafe(uint256,uint256) performs a multiplication on the result of a division:
-rightSideVal = (collateralAmt.mul(collateralToEthPrice)).div(strikeToEthPrice)
-stillSafe = leftSideVal <= rightSideVal.mul(10 ** exp)
Consider ordering multiplication prior division.
There seems to be an inconsistency with the comment here and wanted to make sure that it's not an issue in other parts of the code (which I haven't reviewed yet) that calculate the exercise window.
If _windowSize is a UNIX time, then does it mean that the the window is actually: FROM [_windowSize] to [expiry]?
More likely, _windowSize is number of seconds from expiry...
Report by Slither:
INFO:Detectors:
OptionsContract.setDetails(string,string) (OptionsContract.sol#275-286) contains a tautology or contradiction:
- require(bool,string)(decimals >= 0,1 oToken cannot protect less than the smallest unit of the asset) (OptionsContract.sol#282-285)
function setDetails(string calldata _name, string calldata _symbol)
external
onlyOwner
{
name = _name;
symbol = _symbol;
decimals = uint8(-1 * oTokenExchangeRate.exponent);
require(
decimals >= 0,
"1 oToken cannot protect less than the smallest unit of the asset"
);
}
There's no need to check decimals >= 0 for an uint
.
OptionsContract.calculateOTokens(uint256,OptionsContract.Number) performs a multiplication on the result of a division:
-numeratorVal = (collateralAmt.mul(collateralToEthPrice)).div(strikeToEthPrice)
-numOptions = numeratorVal.mul(10 ** exp).div(denomVal)
Consider ordering multiplication prior division.
Reentrancy in oToken.addERC20CollateralOption(uint256,uint256,address) (oToken.sol#160-167):
External calls:
- addERC20Collateral(msg.sender,amtCollateral) (oToken.sol#165)
- require(bool,string)(collateral.transferFrom(msg.sender,address(this),amt),Could not transfer in collateral tokens) (OptionsContract.sol#362-365)
State variables written after the call(s):
- issueOTokens(amtToCreate,receiver) (oToken.sol#166)
- _balances[account] = _balances[account].add(amount) (@openzeppelin/contracts/token/ERC20/ERC20.sol#176)
- issueOTokens(amtToCreate,receiver) (oToken.sol#166)
- _totalSupply = _totalSupply.add(amount) (@openzeppelin/contracts/token/ERC20/ERC20.sol#175)
Apply the check-effects-interactions pattern.
Reentrancy in OptionsContract.addERC20Collateral(address,uint256):
External calls:
- require(bool,string)(collateral.transferFrom(msg.sender,address(this),amt),Could not transfer in collateral tokens)
State variables written after the call(s):
- _addCollateral(vaultOwner,amt)
- vault.collateral = vault.collateral.add(amt)
Apply the check-effects-interactions pattern.
OptionsContract.hasVault(address).owner (OptionsContract.sol#301) shadows:
- Ownable.owner() (@openzeppelin/contracts/ownership/Ownable.sol#29-31) (function)
Rename the local variable so as not to mistakenly overshadow any state variable/function/modifier/event definitions.
Refer to https://www.figma.com/file/eQhRGVDQcoRTd5455V8FvA/Integration-Tests?node-id=0%3A1 Scenario:Add / Remove / Liquidate / Burn
I think the ABIs files in the ABIs folder are not up-to-date.
OptionsFactory.constructor(OptionsExchange,address)._oracleAddress lacks a zero-check on :
- oracleAddress = _oracleAddress
Check that the address is not zero.
setTokenExchange(address,address) should be declared external:
- MockUniswapFactory.setTokenExchange(address,address) (lib/MockUniswapFactory.sol#29-32)
setTokenWithId(uint256,address) should be declared external:
- MockUniswapFactory.setTokenWithId(uint256,address) (lib/MockUniswapFactory.sol#33-35)
addAndSellETHCollateralOption(uint256,address) should be declared external:
- oToken.addAndSellETHCollateralOption(uint256,address) (oToken.sol#116-129)
addAndSellERC20CollateralOption(uint256,uint256,address) should be declared external:
- oToken.addAndSellERC20CollateralOption(uint256,uint256,address) (oToken.sol#197-211)
getVaultOwnersLength() should be declared external:
- OptionsContract.getVaultOwnersLength() (OptionsContract.sol#225-227)
updateParameters(uint256,uint256,uint256,uint256) should be declared external:
- OptionsContract.updateParameters(uint256,uint256,uint256,uint256) (OptionsContract.sol#236-268)
setDetails(string,string) should be declared external:
- OptionsContract.setDetails(string,string) (OptionsContract.sol#275-286)
transferFee(address) should be declared external:
- OptionsContract.transferFee(address) (OptionsContract.sol#292-298)
removeUnderlying() should be declared external:
- OptionsContract.removeUnderlying() (OptionsContract.sol#446-457)
getVault(address) should be declared external:
- OptionsContract.getVault(address) (OptionsContract.sol#494-511)
burnOTokens(uint256) should be declared external:
- OptionsContract.burnOTokens(uint256) (OptionsContract.sol#527-536)
removeCollateral(uint256) should be declared external:
- OptionsContract.removeCollateral(uint256) (OptionsContract.sol#543-566)
redeemVaultBalance() should be declared external:
- OptionsContract.redeemVaultBalance() (OptionsContract.sol#573-596)
maxOTokensLiquidatable(address) should be declared external:
- OptionsContract.maxOTokensLiquidatable(address) (OptionsContract.sol#602-623)
liquidate(address,uint256) should be declared external:
- OptionsContract.liquidate(address,uint256) (OptionsContract.sol#634-687)
maxOTokensIssuable(uint256) should be declared external:
- OptionsContract.maxOTokensIssuable(uint256) (OptionsContract.sol#895-901)
getPrice(address) should be declared external:
- MockCompoundOracle.getPrice(address) (lib/MockCompoundOracle.sol#10-12)
updatePrice(uint256) should be declared external:
- MockCompoundOracle.updatePrice(uint256) (lib/MockCompoundOracle.sol#14-16)
compareStrings(string,string) should be declared external:
- StringComparator.compareStrings(string,string) (lib/StringComparator.sol#4-7)
mint(address,uint256) should be declared external:
- ERC20Mintable.mint(address,uint256) (@openzeppelin/contracts/token/ERC20/ERC20Mintable.sol#20-23)
getPrice(address) should be declared external:
- Oracle.getPrice(address) (Oracle.sol#58-89)
addMinter(address) should be declared external:
- MinterRole.addMinter(address) (@openzeppelin/contracts/access/roles/MinterRole.sol#27-29)
renounceMinter() should be declared external:
- MinterRole.renounceMinter() (@openzeppelin/contracts/access/roles/MinterRole.sol#31-33)
createOptionsContract(string,int32,string,int32,int32,uint256,int32,string,uint256,uint256) should be declared external:
- OptionsFactory.createOptionsContract(string,int32,string,int32,int32,uint256,int32,string,uint256,uint256) (OptionsFactory.sol#50-96)
getNumberOfOptionsContracts() should be declared external:
- OptionsFactory.getNumberOfOptionsContracts() (OptionsFactory.sol#101-103)
addAsset(string,address) should be declared external:
- OptionsFactory.addAsset(string,address) (OptionsFactory.sol#111-117)
changeAsset(string,address) should be declared external:
- OptionsFactory.changeAsset(string,address) (OptionsFactory.sol#124-133)
deleteAsset(string) should be declared external:
- OptionsFactory.deleteAsset(string) (OptionsFactory.sol#139-147)
borrowBalanceStored(address) should be declared external:
- CTokenInterface.borrowBalanceStored(address) (interfaces/CTokenInterface.sol#46)
exchangeRateCurrent() should be declared external:
- CTokenInterface.exchangeRateCurrent() (interfaces/CTokenInterface.sol#48)
exchangeRateStored() should be declared external:
- CTokenInterface.exchangeRateStored() (interfaces/CTokenInterface.sol#50)
accrueInterest() should be declared external:
- CTokenInterface.accrueInterest() (interfaces/CTokenInterface.sol#54)
name() should be declared external:
- ERC20Detailed.name() (@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol#27-29)
symbol() should be declared external:
- ERC20Detailed.symbol() (@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol#35-37)
decimals() should be declared external:
- ERC20Detailed.decimals() (@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol#51-53)
setCompleted(uint256) should be declared external:
- Migrations.setCompleted(uint256) (Migrations.sol#16-18)
upgrade(address) should be declared external:
- Migrations.upgrade(address) (Migrations.sol#20-23)
sellOTokens(address,address,address,uint256) should be declared external:
- OptionsExchange.sellOTokens(address,address,address,uint256) (OptionsExchange.sol#44-69)
buyOTokens(address,address,address,uint256) should be declared external:
- OptionsExchange.buyOTokens(address,address,address,uint256) (OptionsExchange.sol#78-87)
premiumReceived(address,address,uint256) should be declared external:
- OptionsExchange.premiumReceived(address,address,uint256) (OptionsExchange.sol#96-115)
getPrice(address) should be declared external:
- CompoundOracleInterface.getPrice(address) (interfaces/CompoundOracleInterface.sol#17)
getUnderlyingPrice(ERC20) should be declared external:
- CompoundOracleInterface.getUnderlyingPrice(ERC20) (interfaces/CompoundOracleInterface.sol#19)
renounceOwnership() should be declared external:
- Ownable.renounceOwnership() (@openzeppelin/contracts/ownership/Ownable.sol#55-58)
transferOwnership(address) should be declared external:
- Ownable.transferOwnership(address) (@openzeppelin/contracts/ownership/Ownable.sol#64-66)
totalSupply() should be declared external:
- ERC20.totalSupply() (@openzeppelin/contracts/token/ERC20/ERC20.sol#43-45)
transfer(address,uint256) should be declared external:
- ERC20.transfer(address,uint256) (@openzeppelin/contracts/token/ERC20/ERC20.sol#62-65)
allowance(address,address) should be declared external:
- ERC20.allowance(address,address) (@openzeppelin/contracts/token/ERC20/ERC20.sol#70-72)
approve(address,uint256) should be declared external:
- ERC20.approve(address,uint256) (@openzeppelin/contracts/token/ERC20/ERC20.sol#81-84)
transferFrom(address,address,uint256) should be declared external:
- ERC20.transferFrom(address,address,uint256) (@openzeppelin/contracts/token/ERC20/ERC20.sol#98-102)
increaseAllowance(address,uint256) should be declared external:
- ERC20.increaseAllowance(address,uint256) (@openzeppelin/contracts/token/ERC20/ERC20.sol#116-119)
decreaseAllowance(address,uint256) should be declared external:
- ERC20.decreaseAllowance(address,uint256) (@openzeppelin/contracts/token/ERC20/ERC20.sol#135-138)
Set up an admin for the options contract. The admin should be able to change the following collateralizationRatio, liquidationFactor, liquidationFee, liquidationIncentive, transactionFee
Check if the same asset is being added. Something like:
require( tokens[_asset] != ERC20(_addr), ...)
Whenever the liquidate function gets called, the insurance smart contract should get liquidationFee amount of fees. The max amount of collateral that the liquidator can take out is liquidationFactor * repo.collateral. The amount of collateral taken out is calculated base on how many _oTokens are brought as: _oTokens * strikePrice * (LiquidationIncentive + LiquidationFee)
This is a low priority issue but something you may want to fix at some point.
There should be consistency when looking for the existence of a supported asset and returning the value for that supported asset.
The code below does an explicit check to see if "ETH" is a supported asset:
However in the below code, it's assume that the lack of existence in the token[] is the value for the "ETH" token.
This would be an issue in situations as follows:
In both of the above situations, the rest of the system will break down since isETH() is expected to be ERC20(0).
Each time exercise is called, the exerciser gets strikePrice * _oTokens amount of collateral. The protocol gets transactionFee percent of the repo's collateral. Update the amountExercised = amount paid out the exerciser + the fee taken by the protocol + amountExercised.
Fix the following issues list.
Audit Report by Open Zeppelin
Link: https://blog.openzeppelin.com/private-report-jan-6/
Password: ask for this to the owner
➜ OptionsProtocol git:(dev) node -v
v14.10.1
➜ OptionsProtocol git:(dev) npm -v
6.14.8
➜ OptionsProtocol git:(dev)
➜ OptionsProtocol git:(dev) npm i
[email protected] preinstall /Users/phil/DeFi/opyn/OptionsProtocol/node_modules/scrypt
node node-scrypt-preinstall.js
[email protected] install /Users/phil/DeFi/opyn/OptionsProtocol/node_modules/scrypt
node-gyp rebuild
SOLINK_MODULE(target) Release/copied_files.node
CC(target) Release/obj.target/scrypt_wrapper/src/util/memlimit.o
CC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/keyderivation.o
CC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/pickparams.o
CC(target) Release/obj.target/scrypt_wrapper/src/scryptwrapper/hash.o
LIBTOOL-STATIC Release/scrypt_wrapper.a
CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/lib/crypto/crypto_scrypt.o
CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.o
CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/libcperciva/util/warnp.o
CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/libcperciva/alg/sha256.o
CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/libcperciva/util/insecure_memzero.o
CC(target) Release/obj.target/scrypt_lib/scrypt/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.o
LIBTOOL-STATIC Release/scrypt_lib.a
CXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_common.o
../src/node-boilerplate/scrypt_common.cc:98:12: warning: address of stack memory associated with local
variable 'scrypt_err_description' returned [-Wreturn-stack-address]
return scrypt_err_description.c_str();
^~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
CXX(target) Release/obj.target/scrypt/src/node-boilerplate/scrypt_params_async.o
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
In file included from ../src/node-boilerplate/inc/scrypt_params_async.h:28:
In file included from ../src/node-boilerplate/inc/scrypt_async.h:28:
../src/node-boilerplate/inc/scrypt_common.h:39:14: error: no matching member function for call to 'Get'
N(obj->Get(Nan::New("N").ToLocalChecked())->Uint32Value()),
~~~~~^~~
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3717:43: note: candidate function not
viable: requires 2 arguments, but 1 was provided
V8_WARN_UNUSED_RESULT MaybeLocal Get(Local context,
^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3720:43: note: candidate function not
viable: requires 2 arguments, but 1 was provided
V8_WARN_UNUSED_RESULT MaybeLocal Get(Local context,
^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
In file included from ../src/node-boilerplate/inc/scrypt_params_async.h:28:
In file included from ../src/node-boilerplate/inc/scrypt_async.h:28:
../src/node-boilerplate/inc/scrypt_common.h:40:14: error: no matching member function for call to 'Get'
r(obj->Get(Nan::New("r").ToLocalChecked())->Uint32Value()),
~~~~~^~~
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3717:43: note: candidate function not
viable: requires 2 arguments, but 1 was provided
V8_WARN_UNUSED_RESULT MaybeLocal Get(Local context,
^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3720:43: note: candidate function not
viable: requires 2 arguments, but 1 was provided
V8_WARN_UNUSED_RESULT MaybeLocal Get(Local context,
^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
In file included from ../src/node-boilerplate/inc/scrypt_params_async.h:28:
In file included from ../src/node-boilerplate/inc/scrypt_async.h:28:
../src/node-boilerplate/inc/scrypt_common.h:41:14: error: no matching member function for call to 'Get'
p(obj->Get(Nan::New("p").ToLocalChecked())->Uint32Value()) {}
~~~~~^~~
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3717:43: note: candidate function not
viable: requires 2 arguments, but 1 was provided
V8_WARN_UNUSED_RESULT MaybeLocal Get(Local context,
^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3720:43: note: candidate function not
viable: requires 2 arguments, but 1 was provided
V8_WARN_UNUSED_RESULT MaybeLocal Get(Local context,
^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
In file included from ../src/node-boilerplate/inc/scrypt_params_async.h:28:
../src/node-boilerplate/inc/scrypt_async.h:53:17: warning: 'Call' is deprecated
[-Wdeprecated-declarations]
callback->Call(1, argv);
^
../../nan/nan.h:1741:3: note: 'Call' has been explicitly marked deprecated here
NAN_DEPRECATED inline v8::Localv8::Value
^
../../nan/nan.h:106:40: note: expanded from macro 'NAN_DEPRECATED'
^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
../src/node-boilerplate/inc/scrypt_params_async.h:35:36: error: too few arguments to function call,
single argument 'context' was not specified
maxtime(info[0]->NumberValue()),
~~~~~~~~~~~~~~~~~~~~ ^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:2861:3: note: 'NumberValue' declared here
V8_WARN_UNUSED_RESULT Maybe NumberValue(Local context) const;
^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8config.h:431:31: note: expanded from macro
'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT attribute((warn_unused_result))
^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
../src/node-boilerplate/inc/scrypt_params_async.h:36:39: error: too few arguments to function call,
single argument 'context' was not specified
maxmemfrac(info[1]->NumberValue()),
~~~~~~~~~~~~~~~~~~~~ ^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:2861:3: note: 'NumberValue' declared here
V8_WARN_UNUSED_RESULT Maybe NumberValue(Local context) const;
^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8config.h:431:31: note: expanded from macro
'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT attribute((warn_unused_result))
^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
../src/node-boilerplate/inc/scrypt_params_async.h:37:36: error: too few arguments to function call,
single argument 'context' was not specified
maxmem(info[2]->IntegerValue()),
~~~~~~~~~~~~~~~~~~~~~ ^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:2863:3: note: 'IntegerValue' declared here
V8_WARN_UNUSED_RESULT Maybe<int64_t> IntegerValue(
^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8config.h:431:31: note: expanded from macro
'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT attribute((warn_unused_result))
^
In file included from ../src/node-boilerplate/scrypt_params_async.cc:4:
../src/node-boilerplate/inc/scrypt_params_async.h:38:39: error: too few arguments to function call,
single argument 'context' was not specified
osfreemem(info[3]->IntegerValue())
~~~~~~~~~~~~~~~~~~~~~ ^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:2863:3: note: 'IntegerValue' declared here
V8_WARN_UNUSED_RESULT Maybe<int64_t> IntegerValue(
^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8config.h:431:31: note: expanded from macro
'V8_WARN_UNUSED_RESULT'
#define V8_WARN_UNUSED_RESULT attribute((warn_unused_result))
^
../src/node-boilerplate/scrypt_params_async.cc:23:8: error: no matching member function for call to
'Set'
obj->Set(Nan::New("N").ToLocalChecked(), Nan::New(logN));
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3670:37: note: candidate function not
viable: requires 3 arguments, but 2 were provided
V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context,
^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3673:37: note: candidate function not
viable: requires 3 arguments, but 2 were provided
V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context, uint32_t index,
^
../src/node-boilerplate/scrypt_params_async.cc:24:8: error: no matching member function for call to
'Set'
obj->Set(Nan::New("r").ToLocalChecked(), Nan::New<Integer>(r));
~~~~~^~~
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3670:37: note: candidate function not
viable: requires 3 arguments, but 2 were provided
V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context,
^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3673:37: note: candidate function not
viable: requires 3 arguments, but 2 were provided
V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context, uint32_t index,
^
../src/node-boilerplate/scrypt_params_async.cc:25:8: error: no matching member function for call to
'Set'
obj->Set(Nan::New("p").ToLocalChecked(), Nan::New<Integer>(p));
~~~~~^~~
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3670:37: note: candidate function not
viable: requires 3 arguments, but 2 were provided
V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context,
^
/Users/phil/Library/Caches/node-gyp/14.10.1/include/node/v8.h:3673:37: note: candidate function not
viable: requires 3 arguments, but 2 were provided
V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context, uint32_t index,
^
../src/node-boilerplate/scrypt_params_async.cc:32:13: warning: 'Call' is deprecated
[-Wdeprecated-declarations]
callback->Call(2, argv);
^
../../nan/nan.h:1741:3: note: 'Call' has been explicitly marked deprecated here
NAN_DEPRECATED inline v8::Local<v8::Value>
^
../../nan/nan.h:106:40: note: expanded from macro 'NAN_DEPRECATED'
# define NAN_DEPRECATED __attribute__((deprecated))
^
2 warnings and 10 errors generated.
make: *** [Release/obj.target/scrypt/src/node-boilerplate/scrypt_params_async.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit (/Users/phil/.nvm/versions/node/v14.10.1/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack at ChildProcess.emit (events.js:314:20)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:276:12)
gyp ERR! System Darwin 20.1.0
gyp ERR! command "/Users/phil/.nvm/versions/node/v14.10.1/bin/node" "/Users/phil/.nvm/versions/node/v14.10.1/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/phil/DeFi/opyn/OptionsProtocol/node_modules/scrypt
gyp ERR! node -v v14.10.1
gyp ERR! node-gyp -v v5.1.0
gyp ERR! not ok
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/scrypt):
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] install: `node-gyp rebuild`
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: Exit status 1
up to date in 21.672s
40 packages are looking for funding
run `npm fund` for details
Reentrancy in oToken.addAndSellERC20CollateralOption(uint256,uint256,address) (oToken.sol#197-211):
External calls:
- addERC20Collateral(msg.sender,amtCollateral) (oToken.sol#202)
- require(bool,string)(collateral.transferFrom(msg.sender,address(this),amt),Could not transfer in collateral tokens) (OptionsContract.sol#362-365)
State variables written after the call(s):
- issueOTokens(amtToCreate,address(this)) (oToken.sol#203)
- _balances[account] = _balances[account].add(amount) (@openzeppelin/contracts/token/ERC20/ERC20.sol#176)
- issueOTokens(amtToCreate,address(this)) (oToken.sol#203)
- _totalSupply = _totalSupply.add(amount) (@openzeppelin/contracts/token/ERC20/ERC20.sol#175)
Apply the check-effects-interactions pattern.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.