Skip to content

Commit

Permalink
Merge pull request #33 from gititGoro/c4-audit-fixes
Browse files Browse the repository at this point in the history
C4 audit fixes
  • Loading branch information
gititGoro authored Jul 4, 2022
2 parents 11ddb9e + 1422434 commit 2c58a02
Show file tree
Hide file tree
Showing 21 changed files with 89 additions and 116 deletions.
2 changes: 1 addition & 1 deletion contracts/DAO/FlashGovernanceArbiter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ contract FlashGovernanceArbiter is Governable {
* @param amount is the amount of the deposit_asset to be put up as decision collateral.
* @param target is the contract that will be affected by the flash governance decision.
*/
event flashDecision(address actor, address deposit_asset, uint256 amount, address target);
event flashDecision(address indexed actor, address indexed deposit_asset, uint256 amount, address indexed target);

mapping(address => bool) enforceLimitsActive;

Expand Down
28 changes: 13 additions & 15 deletions contracts/DAO/LimboDAO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ struct AssetClout {
contract LimboDAO is Ownable {
using SafeERC20 for IERC20;
event daoKilled(address newOwner);
event proposalLodged(address proposal, address proposer);
event voteCast(address voter, address proposal, int256 fateCast);
event proposalLodged(address indexed proposal, address indexed proposer);
event voteCast(address indexed voter, address indexed proposal, int256 fateCast);
event assetApproval(address asset, bool appoved);
event proposalExecuted(address proposal, bool status);
event assetBurnt(address burner, address asset, uint256 fateCreated);
event proposalExecuted(address indexed proposal, bool status);
event assetBurnt(address indexed burner, address indexed asset, uint256 fateCreated);

uint256 constant ONE = 1 ether;

Expand All @@ -102,10 +102,9 @@ contract LimboDAO is Ownable {
mapping(address => mapping(address => AssetClout)) public stakedUserAssetWeight; //user->asset->weight

ProposalState public currentProposalState;
ProposalState public previousProposalState;

// Since staking EYE precludes it from earning Flan on Limbo, fateToFlan can optionally be set to a non zero number to allow fat holders to spend their fate for Flan.
uint256 public fateToFlan;
// Since staking EYE precludes it from earning Flan on Limbo, flanPerFate can optionally be set to a non zero number to allow fat holders to spend their fate for Flan.
uint256 public flanPerFate;

modifier isLive() {
if (!domainConfig.live) {
Expand All @@ -120,7 +119,6 @@ contract LimboDAO is Ownable {
}

function nextProposal() internal {
previousProposalState = currentProposalState;
currentProposalState.proposal.setLocked(false);
currentProposalState.proposal = Proposal(address(0));
currentProposalState.fate = 0;
Expand Down Expand Up @@ -213,7 +211,7 @@ contract LimboDAO is Ownable {
}
for (uint256 i = 0; i < uniMetaLPs.length; i++) {
if (IUniswapV2Pair(uniMetaLPs[i]).factory() != uniFactory)
revert UniswapV2FactoryMismatch(IUniswapV2Pair(uniMetaLPs[i]).factory(), sushiFactory);
revert UniswapV2FactoryMismatch(IUniswapV2Pair(uniMetaLPs[i]).factory(), uniFactory);
_setApprovedAsset(uniMetaLPs[i], true, true, 0);
}
}
Expand All @@ -233,15 +231,15 @@ contract LimboDAO is Ownable {
}

// ///@notice optional conversion rate of Fate to Flan
function setFateToFlan(uint256 rate) public onlySuccessfulProposal {
fateToFlan = rate;
function setFlanPerFate(uint256 rate) public onlySuccessfulProposal {
flanPerFate = rate;
}

// ///@notice caller spends their Fate to earn Flan
function convertFateToFlan(uint256 fate) public returns (uint256 flan) {
if (fateToFlan == 0) revert FateToFlanConversionDisabled();
function convertFlanPerFate(uint256 fate) public returns (uint256 flan) {
if (flanPerFate == 0) revert FlanPerFateConversionDisabled();
fateState[msg.sender].fateBalance -= fate;
flan = (fateToFlan * fate) / ONE;
flan = (flanPerFate * fate) / ONE;
Flan(domainConfig.flan).mint(msg.sender, flan);
}

Expand Down Expand Up @@ -271,7 +269,7 @@ contract LimboDAO is Ownable {
///@notice handles proposal voting logic.
///@param proposal contract to be voted on
///@param fate positive is YES, negative is NO. Absolute value is deducted from caller.
function vote(address proposal, int256 fate) public incrementFate isLive {
function vote(address proposal, int256 fate) public isLive incrementFate{
//this is just to protect users with out of sync UIs
if (proposal != address(currentProposalState.proposal))
revert ProposalMismatch(proposal, address(currentProposalState.proposal));
Expand Down
2 changes: 1 addition & 1 deletion contracts/DAO/ProposalFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import "../periphery/Errors.sol";
abstract contract Proposal {
string public description;
bool public locked;
LimboDAOLike DAO;
LimboDAOLike immutable DAO;

constructor(address dao, string memory _description) {
DAO = LimboDAOLike(dao);
Expand Down
2 changes: 1 addition & 1 deletion contracts/DAO/Proposals/TurnOnFateMintingProposal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ contract TurnOnFateMintingProposal is Proposal {
}

function execute() internal override returns (bool) {
DAO.setFateToFlan(rate);
DAO.setFlanPerFate(rate);
return true;
}
}
35 changes: 18 additions & 17 deletions contracts/Limbo.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import "./openzeppelin/Ownable.sol";
import "./facades/LimboDAOLike.sol";
import "./facades/Burnable.sol";
import "./facades/BehodlerLike.sol";
Expand Down Expand Up @@ -195,11 +194,11 @@ library MigrationLib {
uint256 lpMinted = AMMHelper(crossingConfig.ammHelper).stabilizeFlan(scxBalance);
//reward caller and update soul state

(bool noException, bytes memory result) = address(flan).call(
abi.encodeWithSignature("mint(address,uint)", msg.sender, crossingConfig.migrationInvocationReward)
);
bool success = abi.decode(result, (bool));
if (!noException || !success) {
uint256 flanOfCallerBefore = flan.balanceOf(msg.sender);
uint256 reward = crossingConfig.migrationInvocationReward;
flan.mint(msg.sender, reward);
uint256 change = flan.balanceOf(msg.sender) - flanOfCallerBefore;
if (change != reward) {
revert InvocationRewardFailed(msg.sender);
}

Expand All @@ -218,14 +217,14 @@ contract Limbo is Governable {
using MigrationLib for address;
using CrossingLib for CrossingParameters;

event SoulUpdated(address soul, uint256 fps);
event Staked(address staker, address soul, uint256 amount);
event Unstaked(address staker, address soul, uint256 amount);
event TokenListed(address token, uint256 amount, uint256 scxfln_LP_minted);
event SoulUpdated(address indexed soul, uint256 fps);
event Staked(address indexed staker, address indexed soul, uint256 amount);
event Unstaked(address indexed staker, address indexed soul, uint256 amount);
event TokenListed(address indexed token, uint256 amount, uint256 scxfln_LP_minted);

event ClaimedReward(address staker, address soul, uint256 index, uint256 amount);
event ClaimedReward(address indexed staker, address indexed soul, uint256 index, uint256 amount);

event BonusPaid(address token, uint256 index, address recipient, uint256 bonus);
event BonusPaid(address indexed token, uint256 index, address indexed recipient, uint256 bonus);

struct User {
uint256 stakedAmount;
Expand Down Expand Up @@ -254,10 +253,10 @@ contract Limbo is Governable {

///@dev soul->owner->unstaker->amount
mapping(address => mapping(address => mapping(address => uint256))) public unstakeApproval;
FlanLike Flan;
FlanLike immutable Flan;

modifier enabled() {
if(!protocolEnabled){
if (!protocolEnabled) {
revert ProtocolDisabled();
}
_;
Expand All @@ -273,8 +272,8 @@ contract Limbo is Governable {
uint256 daiThreshold
) public governanceApproved(false) {
Soul storage soul = currentSoul(token);
if(soul.soulType != SoulType.threshold){
revert InvalidSoulType(token, uint(soul.soulType), uint(SoulType.threshold));
if (soul.soulType != SoulType.threshold) {
revert InvalidSoulType(token, uint256(soul.soulType), uint256(SoulType.threshold));
}
uint256 fps = AMMHelper(crossingConfig.ammHelper).minAPY_to_FPS(desiredAPY, daiThreshold);
flashGoverner().enforceTolerance(soul.flanPerSecond, fps);
Expand Down Expand Up @@ -480,7 +479,8 @@ contract Limbo is Governable {
revert InvalidSoulState(token, uint256(soul.state));
}
updateSoul(token, soul);
User storage user = userInfo[token][holder][latestIndex[token]];
uint256 index = latestIndex[token];
User storage user = userInfo[token][holder][index];
if (user.stakedAmount < amount) {
revert ExcessiveWithdrawalRequest(token, amount, user.stakedAmount);
}
Expand All @@ -490,6 +490,7 @@ contract Limbo is Governable {
user.stakedAmount = user.stakedAmount - amount;
IERC20(token).safeTransfer(address(unstaker), amount);
rewardAdjustDebt(unstaker, pending, soul.accumulatedFlanPerShare, user);
emit ClaimedReward(unstaker, token, index, pending);
emit Unstaked(unstaker, token, amount);
}
}
Expand Down
20 changes: 3 additions & 17 deletions contracts/UniswapHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ contract UniswapHelper is Governable, AMMHelper {
uint256 constant EXA = 1e18;

//needs to be updated for future Martian, Lunar and Venusian blockchains although I suspect Lunar colonies will be very Terracentric because of low time lag.
uint256 constant year = (1 days * 365);
uint256 constant year = 31536000; // seconds in 365 day year

constructor(address _limbo, address limboDAO) Governable(limboDAO) {
limbo = _limbo;
Expand Down Expand Up @@ -114,10 +114,6 @@ contract UniswapHelper is Governable, AMMHelper {
address fln_scx = VARS.factory.getPair(flan, behodler);
address dai_scx = VARS.factory.getPair(VARS.DAI, behodler);
address scx__fln_scx = VARS.factory.getPair(behodler, fln_scx);
// console.log("dai %s", VARS.DAI);
// console.log("fln_scx %s", fln_scx);
// console.log("dai_scx %s", dai_scx);
// console.log("scx__fln_scx %s", scx__fln_scx);

address zero = address(0);

Expand Down Expand Up @@ -168,26 +164,16 @@ contract UniswapHelper is Governable, AMMHelper {
PriceTiltVARS memory priceTilting = getPriceTiltVARS();
uint256 transferredSCX = (mintedSCX * 98) / 100;
uint256 finalSCXBalanceOnLP = (transferredSCX) + priceTilting.currentSCXInFLN_SCX;
// console.log(
// "finalSCXBalanceOnLP %s, currentSCXInFLN_SCX %s",
// finalSCXBalanceOnLP,
// priceTilting.currentSCXInFLN_SCX
// );
// console.log(
// "actual balance of SCX in FLN_SCX %s",
// IERC20(VARS.behodler).balanceOf(address(VARS.oracleSet.fln_scx))
// );

uint256 DesiredFinalFlanOnLP = (finalSCXBalanceOnLP * priceTilting.FlanPerSCX) / SPOT;
// console.log("FlanPerSCX %s ", priceTilting.FlanPerSCX);
// console.log("desiredFlanOnLP %s", DesiredFinalFlanOnLP);

address pair = address(VARS.oracleSet.fln_scx);

if (priceTilting.currentFLNInFLN_SCX < DesiredFinalFlanOnLP) {
uint256 flanToMint = ((DesiredFinalFlanOnLP - priceTilting.currentFLNInFLN_SCX) *
(100 - VARS.priceBoostOvershoot)) / 100;
flanToMint = flanToMint == 0 ? DesiredFinalFlanOnLP - priceTilting.currentFLNInFLN_SCX : flanToMint;
FlanLike(VARS.flan).mint(pair, flanToMint);
// console.log("MINTED SCX %s, scx balance %s", transferredSCX, IERC20(VARS.behodler).balanceOf(address(this)));

IERC20(VARS.behodler).transfer(pair, transferredSCX);
{
Expand Down
2 changes: 2 additions & 0 deletions contracts/facades/FlanLike.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ abstract contract FlanLike {
function setBurnOnTransferFee(uint8 fee) public virtual;

function burn(uint256 amount) public virtual returns (bool);

function balanceOf(address holder) public virtual returns (uint);
}
2 changes: 1 addition & 1 deletion contracts/facades/LimboDAOLike.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,5 @@ abstract contract LimboDAOLike {
address
);

function setFateToFlan(uint256 rate) public virtual;
function setFlanPerFate(uint256 rate) public virtual;
}
2 changes: 1 addition & 1 deletion contracts/facades/TokenProxyLike.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
abstract contract TokenProxyLike {
address internal baseToken;
address internal immutable baseToken;
uint constant internal ONE = 1 ether;
constructor (address _baseToken) {
baseToken=_baseToken;
Expand Down
2 changes: 1 addition & 1 deletion contracts/openzeppelin/ERC20Burnable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ contract ERC20 is IERC20, IERC20Metadata {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][msg.sender];

if (amount > currentAllowance) {
if (currentAllowance != type(uint).max && amount > currentAllowance) {
revert AllowanceExceeded(currentAllowance, amount);
}
_approve(sender, msg.sender, currentAllowance - amount);
Expand Down
2 changes: 1 addition & 1 deletion contracts/openzeppelin/IERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

pragma solidity ^0.8.13;
import "../periphery/Errors.sol";
import "hardhat/console.sol";
// import "hardhat/console.sol";

/**
* @dev Interface of the ERC20 standard as defined in the EIP.
Expand Down
3 changes: 1 addition & 2 deletions contracts/periphery/BehodlerLite/BehodlerLite.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import "hardhat/console.sol";
// import "hardhat/console.sol";
import "./CommonIERC20.sol";

abstract contract Burnable {
Expand Down Expand Up @@ -356,7 +356,6 @@ contract BehodlerLite is ScarcityLite {
}

modifier onlyValidToken(address token) {
if (!validTokens[token]) console.log("BEHODLER LITE: invalid token %s", token);
require(lachesis == address(0) || validTokens[token], "BehodlerLite: tokenInvalid");
_;
}
Expand Down
4 changes: 1 addition & 3 deletions contracts/periphery/BehodlerLite/LiquidityReceiver.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import "hardhat/console.sol";
// import "hardhat/console.sol";

enum FeeExemption {
NO_EXEMPTIONS,
Expand Down Expand Up @@ -490,7 +490,6 @@ contract PyroToken is ERC20, ReentrancyGuard {
//fee on transfer tokens
uint256 trueTransfer = config.baseToken.balanceOf(address(this)) - initialBalance;
uint256 pyro = ( ONE* trueTransfer) / _redeemRate;
console.log("minted pyro %s, baseTokenAmount %s", pyro, trueTransfer);
_mint(recipient, pyro);
emit Transfer(address(0), recipient, uint128(pyro), 0);
return pyro;
Expand Down Expand Up @@ -818,7 +817,6 @@ contract LiquidityReceiver is Ownable {
}

constructor(address _lachesis) {
console.log('lachesis %s',_lachesis);
config.lachesis = LachesisLike(_lachesis);
}

Expand Down
6 changes: 1 addition & 5 deletions contracts/periphery/BehodlerLite/PyroWethProxy.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import "hardhat/console.sol";
// import "hardhat/console.sol";

contract Ownable {
address private _owner;
Expand Down Expand Up @@ -599,10 +599,6 @@ contract WETH10 is IWETH10 {

uint256 allowed = allowance[from][msg.sender];
if (allowed != type(uint256).max) {
if (allowed < value) {
console.log("FROM: %s TO: %s", from, to);
console.log("allowed: %s value: %s", allowed, value);
}
require(allowed >= value, "WETH: request exceeds allowance");
uint256 reduced = allowed - value;
allowance[from][msg.sender] = reduced;
Expand Down
2 changes: 1 addition & 1 deletion contracts/periphery/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ error AssetMustBeEYE (address eye, address invalidAsset);
error FlashGovernerNotSet();
error ProposalMismatch(address proposal, address currrentProposal);
error OnlyProposalFactory(address msg_sender, address factory);
error FateToFlanConversionDisabled();
error FlanPerFateConversionDisabled();
error UniswapV2FactoryMismatch (address pairFactory,address trueFactory);
error InvalidVoteCast(int fateCast, int currentProposalFate);
error VotingPeriodOver (uint blockTime,uint proposalStartTime,uint votingDuration);
Expand Down
2 changes: 0 additions & 2 deletions contracts/periphery/LimboOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ contract LimboOracle is Governable {
address tokenOut,
uint256 amountIn
) external view validPair(tokenIn, tokenOut) returns (uint256 amountOut) {
console.log("correct oracle");
IUniswapV2Pair pair = IUniswapV2Pair(factory.getPair(tokenIn, tokenOut));
PairMeasurement memory measurement = pairMeasurements[address(pair)];

Expand All @@ -114,7 +113,6 @@ contract LimboOracle is Governable {
amountOut = (measurement.price1Average.mul(amountIn)).decode144();
}

console.log("In oracle amountOut %s", amountOut);
if (amountOut == 0) {
revert UpdateOracle(tokenIn, tokenOut, amountIn);
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/periphery/UniswapV2/UniswapV2Router02.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import "hardhat/console.sol";
// import "hardhat/console.sol";
interface IUniswapV2Pair {
event Approval(address indexed owner, address indexed spender, uint256 value);
event Transfer(address indexed from, address indexed to, uint256 value);
Expand Down
Loading

0 comments on commit 2c58a02

Please sign in to comment.