Skip to content

Commit

Permalink
Revert "71 audit missing assert verification on transfer of tokens (#81
Browse files Browse the repository at this point in the history
…)"

This reverts commit 79d913a.
  • Loading branch information
MiguelBits authored Sep 30, 2022
1 parent 79d913a commit 5841175
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 433 deletions.
2 changes: 1 addition & 1 deletion script/DeployContract.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ contract DeployScript is Script {

function setUp() public {
vaultFactory = new VaultFactory(admin,WETH,admin);
controller = new Controller(address(vaultFactory), arbitrum_sequencer);
controller = new Controller(address(vaultFactory),admin, arbitrum_sequencer);

vm.prank(admin);
vaultFactory.setController(address(controller));
Expand Down
2 changes: 1 addition & 1 deletion script/DeployGoerli.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ contract DeployGoerliScript is Script {

// setUp();
vaultFactory = new VaultFactory(admin,WETH,admin);
controller = new Controller(address(vaultFactory), arbitrum_sequencer);
controller = new Controller(address(vaultFactory),admin, arbitrum_sequencer);

vaultFactory.setController(address(controller));

Expand Down
178 changes: 78 additions & 100 deletions src/Controller.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import "@chainlink/interfaces/AggregatorV3Interface.sol";
import "@chainlink/interfaces/AggregatorV2V3Interface.sol";

contract Controller {
address public immutable admin;
VaultFactory public immutable vaultFactory;
AggregatorV2V3Interface internal sequencerUptimeFeed;

uint256 private constant GRACE_PERIOD_TIME = 3600;
uint256 public constant VAULTS_LENGTH = 2;

/*//////////////////////////////////////////////////////////////
ERRORS
Expand All @@ -21,15 +23,16 @@ contract Controller {
error SequencerDown();
error GracePeriodNotOver();
error ZeroAddress();
error EpochFinishedAlready();
error NotZeroTVL();
error PriceNotAtStrikePrice(int256 price);
error EpochNotStarted();
error EpochExpired();
error OraclePriceZero();
error RoundIDOutdated();
error TimestampZero();
error AddressNotAdmin();
error EpochNotExist();
error EpochNotExpired();
error VaultNotZeroTVL();

/*//////////////////////////////////////////////////////////////
EVENTS
Expand All @@ -52,31 +55,84 @@ contract Controller {
int256 depegPrice
);

/* solhint-disable var-name-mixedcase */
struct VaultTVL {
uint256 RISK_claimTVL;
uint256 RISK_finalTVL;
uint256 INSR_claimTVL;
uint256 INSR_finalTVL;
}
/* solhint-enable var-name-mixedcase */

/*//////////////////////////////////////////////////////////////
MODIFIERS
//////////////////////////////////////////////////////////////*/

/** @notice Only admin addresses can call functions that use this modifier
*/
modifier onlyAdmin() {
if(msg.sender != admin)
revert AddressNotAdmin();
_;
}

/** @notice Modifier to ensure market exists, current market epoch time and price are valid
* @param marketIndex Target market index
* @param epochEnd End of epoch set for market
*/
modifier isDisaster(uint256 marketIndex, uint256 epochEnd) {
address[] memory vaultsAddress = vaultFactory.getVaults(marketIndex);
if(
vaultsAddress.length != VAULTS_LENGTH
)
revert MarketDoesNotExist(marketIndex);

address vaultAddress = vaultsAddress[0];
Vault vault = Vault(vaultAddress);

if(vault.idExists(epochEnd) == false)
revert EpochNotExist();

if(
vault.strikePrice() < getLatestPrice(vault.tokenInsured())
)
revert PriceNotAtStrikePrice(getLatestPrice(vault.tokenInsured()));

if(
vault.idEpochBegin(epochEnd) > block.timestamp)
revert EpochNotStarted();

if(
block.timestamp > epochEnd
)
revert EpochExpired();
_;
}

/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/

/** @notice Contract constructor
* @param _factory VaultFactory address
* @param _admin Admin address
* @param _l2Sequencer Arbitrum sequencer address
*/
constructor(
address _factory,
address _admin,
address _l2Sequencer
) {
if(_admin == address(0))
revert ZeroAddress();

if(_factory == address(0))
revert ZeroAddress();

if(_l2Sequencer == address(0))
revert ZeroAddress();

admin = _admin;
vaultFactory = VaultFactory(_factory);
sequencerUptimeFeed = AggregatorV2V3Interface(_l2Sequencer);
}
Expand All @@ -91,38 +147,17 @@ contract Controller {
*/
function triggerDepeg(uint256 marketIndex, uint256 epochEnd)
public
isDisaster(marketIndex, epochEnd)
{
address[] memory vaultsAddress = vaultFactory.getVaults(marketIndex);
Vault insrVault = Vault(vaultsAddress[0]);
Vault riskVault = Vault(vaultsAddress[1]);

if(
vaultsAddress[0] == address(0) || vaultsAddress[1] == address(0)
)
revert MarketDoesNotExist(marketIndex);

if(insrVault.idExists(epochEnd) == false)
revert EpochNotExist();

if(
insrVault.strikePrice() <= getLatestPrice(insrVault.tokenInsured())
)
revert PriceNotAtStrikePrice(getLatestPrice(insrVault.tokenInsured()));

if(
insrVault.idEpochBegin(epochEnd) > block.timestamp)
revert EpochNotStarted();

if(
block.timestamp > epochEnd
)
revert EpochExpired();

//require this function cannot be called twice in the same epoch for the same vault
if(insrVault.idEpochEnded(epochEnd))
revert EpochFinishedAlready();
if(riskVault.idEpochEnded(epochEnd))
revert EpochFinishedAlready();
if(insrVault.idFinalTVL(epochEnd) != 0)
revert NotZeroTVL();
if(riskVault.idFinalTVL(epochEnd) != 0)
revert NotZeroTVL();

insrVault.endEpoch(epochEnd);
riskVault.endEpoch(epochEnd);
Expand All @@ -140,17 +175,6 @@ contract Controller {
insrVault.idFinalTVL(epochEnd)
);

AggregatorV3Interface priceFeed = AggregatorV3Interface(
vaultFactory.tokenToOracle(insrVault.tokenInsured())
);
(
,
int256 price,
,
,

) = priceFeed.latestRoundData();

emit DepegInsurance(
keccak256(
abi.encodePacked(
Expand All @@ -163,7 +187,7 @@ contract Controller {
true,
epochEnd,
block.timestamp,
price
getLatestPrice(insrVault.tokenInsured())
);
}

Expand All @@ -172,6 +196,9 @@ contract Controller {
* @param epochEnd End of epoch set for market
*/
function triggerEndEpoch(uint256 marketIndex, uint256 epochEnd) public {
if(
vaultFactory.getVaults(marketIndex).length != VAULTS_LENGTH)
revert MarketDoesNotExist(marketIndex);
if(
block.timestamp <= epochEnd)
revert EpochNotExpired();
Expand All @@ -180,20 +207,15 @@ contract Controller {

Vault insrVault = Vault(vaultsAddress[0]);
Vault riskVault = Vault(vaultsAddress[1]);

if(
vaultsAddress[0] == address(0) || vaultsAddress[1] == address(0)
)
revert MarketDoesNotExist(marketIndex);

if(insrVault.idExists(epochEnd) == false || riskVault.idExists(epochEnd) == false)
revert EpochNotExist();

//require this function cannot be called twice in the same epoch for the same vault
if(insrVault.idEpochEnded(epochEnd))
revert EpochFinishedAlready();
if(riskVault.idEpochEnded(epochEnd))
revert EpochFinishedAlready();
if(insrVault.idFinalTVL(epochEnd) != 0)
revert NotZeroTVL();
if(riskVault.idFinalTVL(epochEnd) != 0)
revert NotZeroTVL();

insrVault.endEpoch(epochEnd);
riskVault.endEpoch(epochEnd);
Expand Down Expand Up @@ -224,57 +246,10 @@ contract Controller {
getLatestPrice(insrVault.tokenInsured())
);
}
/** @notice Trigger epoch invalid when one vault has 0 TVL
* @param marketIndex Target market index
* @param epochEnd End of epoch set for market
*/
function triggerNullEpoch(uint256 marketIndex, uint256 epochEnd) public {
address[] memory vaultsAddress = vaultFactory.getVaults(marketIndex);

Vault insrVault = Vault(vaultsAddress[0]);
Vault riskVault = Vault(vaultsAddress[1]);

if(
vaultsAddress[0] == address(0) || vaultsAddress[1] == address(0)
)
revert MarketDoesNotExist(marketIndex);

if(insrVault.idExists(epochEnd) == false || riskVault.idExists(epochEnd) == false)
revert EpochNotExist();

if(block.timestamp < insrVault.idEpochBegin(epochEnd))
revert EpochNotStarted();

if(insrVault.idExists(epochEnd) == false || riskVault.idExists(epochEnd) == false)
revert EpochNotExist();

//require this function cannot be called twice in the same epoch for the same vault
if(insrVault.idEpochEnded(epochEnd))
revert EpochFinishedAlready();
if(riskVault.idEpochEnded(epochEnd))
revert EpochFinishedAlready();

//set claim TVL to 0 if total assets are 0
if(insrVault.totalAssets(epochEnd) == 0){
insrVault.endEpoch(epochEnd);
riskVault.endEpoch(epochEnd);

insrVault.setClaimTVL(epochEnd, 0);
riskVault.setClaimTVL(epochEnd, riskVault.idFinalTVL(epochEnd));

riskVault.setEpochNull(epochEnd);
}
else if(riskVault.totalAssets(epochEnd) == 0){
insrVault.endEpoch(epochEnd);
riskVault.endEpoch(epochEnd);

insrVault.setClaimTVL(epochEnd, insrVault.idFinalTVL(epochEnd) );
riskVault.setClaimTVL(epochEnd, 0);

insrVault.setEpochNull(epochEnd);
}
else revert VaultNotZeroTVL();
}
/*//////////////////////////////////////////////////////////////
ADMIN SETTINGS
//////////////////////////////////////////////////////////////*/

/*//////////////////////////////////////////////////////////////
GETTERS
Expand Down Expand Up @@ -317,7 +292,7 @@ contract Controller {
uint80 roundID,
int256 price,
,
,
uint256 timeStamp,
uint80 answeredInRound
) = priceFeed.latestRoundData();

Expand All @@ -336,6 +311,9 @@ contract Controller {
if(answeredInRound < roundID)
revert RoundIDOutdated();

if(timeStamp == 0)
revert TimestampZero();

return price;
}

Expand Down
10 changes: 5 additions & 5 deletions src/SemiFungibleVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ abstract contract SemiFungibleVault is ERC1155Supply {
* @param owner receiver who will own of the tokens representing this deposit
* @param id Vault id
* @param assets Amount of owner assets to deposit into vault
* @param shares Amount of shares to mint for owner
*/
event Deposit(
address caller,
address indexed owner,
uint256 indexed id,
uint256 assets
uint256 assets,
uint256 shares
);

/** @notice Withdraw from vault when event is emitted
Expand Down Expand Up @@ -90,7 +92,7 @@ abstract contract SemiFungibleVault is ERC1155Supply {

_mint(receiver, id, assets, EMPTY);

emit Deposit(msg.sender, receiver, id, assets);
emit Deposit(msg.sender, receiver, id, assets, assets);
}

/** @notice Triggers withdraw from vault and burns receivers' shares
Expand Down Expand Up @@ -126,9 +128,7 @@ abstract contract SemiFungibleVault is ERC1155Supply {
/**@notice Returns total assets for token
* @param _id uint256 token id of token
*/
function totalAssets(uint256 _id) public view virtual returns (uint256){
return totalSupply(_id);
}
function totalAssets(uint256 _id) public view virtual returns (uint256);

/**
@notice Shows assets conversion output from withdrawing assets
Expand Down
Loading

0 comments on commit 5841175

Please sign in to comment.