Skip to content

Commit 7bba933

Browse files
committed
resolved merge conflicts with feat/SolaceNative
2 parents 0df2cd8 + df464fa commit 7bba933

23 files changed

+9568
-33349
lines changed

contracts/airdrop/MerkleDistributor.sol

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
55
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
66
import "../interfaces/airdrop/IMerkleDistributor.sol";
77
import "../utils/Governable.sol";
8-
// import "hardhat/console.sol";
98

109
contract MerkleDistributor is IMerkleDistributor, Governable {
1110
address public immutable override token; // Airdrop token
@@ -75,12 +74,4 @@ contract MerkleDistributor is IMerkleDistributor, Governable {
7574
if (!IERC20(token).transfer(governance, balance)) revert FailedGovernorRecover(balance);
7675
emit GovernorRecoverAirdropTokens(balance);
7776
}
78-
}
79-
80-
// Useful resources
81-
82-
// Modified from https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol
83-
// https://github.com/Anish-Agnihotri/merkle-airdrop-starter/blob/master/contracts/src/MerkleClaimERC20.sol
84-
85-
// Use Custom errors - https://blog.soliditylang.org/2021/04/21/custom-errors/ - instead of require strings
86-
// Cheaper in deploy and runtime costs, able to convey dynamic information
77+
}

contracts/interfaces/native/IGaugeController.sol

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import "./GaugeStructs.sol";
1111
* Current gauge weights can be obtained through [`getGaugeWeight()`](#getgaugeweight) and [`getAllGaugeWeights()`](#getallgaugeweights)
1212
*
1313
* Only governance can make mutator calls to GaugeController.sol. There are no unpermissioned external mutator calls in this contract.
14-
*
14+
*
1515
* After every epoch, governance must call [`updateGaugeWeights()`](#updategaugeweights). This will process the last epoch's votes (stored in this contract).
16-
*
16+
*
1717
* Individual voters register and manage their vote through voting contracts that conform to IGaugeVoting.
1818
*
1919
* Governance can [`addGauge()`](#addgauge) or [`pauseGauge()`](#pausegauge).
@@ -27,7 +27,7 @@ interface IGaugeController {
2727
/// @notice Thrown when zero address is given as an argument.
2828
/// @param contractName Name of contract for which zero address was incorrectly provided.
2929
error ZeroAddressInput(string contractName);
30-
30+
3131
/// @notice Thrown when array arguments are mismatched in length;
3232
error ArrayArgumentsLengthMismatch();
3333

@@ -174,7 +174,7 @@ interface IGaugeController {
174174
* @return numPausedGauges
175175
*/
176176
function getNumPausedGauges() external view returns (uint256 numPausedGauges);
177-
177+
178178
/**
179179
* @notice Get gauge name.
180180
* @param gaugeID_ The ID of the gauge to query.
@@ -238,7 +238,7 @@ interface IGaugeController {
238238
* @return votersCount Number of votes.
239239
*/
240240
function getVotersCount(address votingContract_) external view returns (uint256 votersCount);
241-
241+
242242
/**
243243
* @notice Get current epoch length in seconds.
244244
* @return epochLength
@@ -337,7 +337,7 @@ interface IGaugeController {
337337
* @param tokenholder_ Address of new tokenholder.
338338
*/
339339
function removeTokenholder(address tokenholder_) external;
340-
340+
341341
/**
342342
* @notice Set annual rate-on-line for selected gaugeIDs
343343
* @dev 1e18 => 100%

contracts/interfaces/native/IUnderwritingEquity.sol

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,17 @@ interface IUnderwritingEquity is IERC20Metadata {
2424
***************************************/
2525

2626
/// @notice Emitted when a deposit is made.
27-
event DepositMade(address user, uint256 uwpAmount, uint256 uweAmount);
27+
event DepositMade(address indexed user, uint256 uwpAmount, uint256 uweAmount);
2828
/// @notice Emitted when a withdraw is made.
29-
event WithdrawMade(address user, uint256 uwpAmount, uint256 uweAmount);
29+
event WithdrawMade(address indexed user, uint256 uwpAmount, uint256 uweAmount);
3030
/// @notice Emitted when uwp is loaned.
3131
event UwpLoaned(uint256 uwpAmount, address receiver);
3232
/// @notice Emitted when issue fee is set.
3333
event IssueFeeSet(uint256 fee, address receiver);
3434
/// @notice Emitted when pause is set.
3535
event PauseSet(bool depositIsPaused, bool withdrawIsPaused, bool lendIsPaused);
36+
/// @notice Emitted when the [`UWP`](./../../native/UnderwritingPool) contract is set.
37+
event UwpSet(address uwp);
3638

3739
/***************************************
3840
VIEW FUNCTIONS
@@ -134,9 +136,17 @@ interface IUnderwritingEquity is IERC20Metadata {
134136

135137
/**
136138
* @notice Pauses or unpauses contract functionality.
139+
* Can only be called by the current [**governor**](/docs/protocol/governance).
137140
* @param depositIsPaused True to pause deposit, false to unpause.
138141
* @param withdrawIsPaused True to pause withdraw, false to unpause.
139142
* @param lendIsPaused True to pause lend, false to unpause.
140143
*/
141144
function setPause(bool depositIsPaused, bool withdrawIsPaused, bool lendIsPaused) external;
145+
146+
/**
147+
* @notice Upgrades the [`UWP`](./../../native/UnderwritingPool) contract.
148+
* Can only be called by the current [**governor**](/docs/protocol/governance).
149+
* @param uwp_ The address of the new [`UWP`](./../../native/UnderwritingPool).
150+
*/
151+
function setUwp(address uwp_) external;
142152
}

contracts/interfaces/native/IUnderwritingLockVoting.sol

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,26 @@ import "./GaugeStructs.sol";
88
* @title IUnderwritingLockVoting
99
* @author solace.fi
1010
* @notice Enables individual votes in Solace Native insurance gauges for owners of [`UnderwritingLocker`](./UnderwritingLocker).
11-
*
11+
*
1212
* Any address owning an underwriting lock can vote and will have a votePower that can be viewed with [`getVotePower()`](#getVotePower)
1313
* An address' vote power is the sum of the vote power of its owned locks.
1414
* A lock's vote power scales linearly with locked amount, and through a sqrt formula with lock duration
1515
* Users cannot view the vote power of an individual lock through this contract, only the total vote power of an address.
1616
* This is an intentional design choice to abstract locks away from address-based voting.
17-
*
17+
*
1818
* Voters can set a delegate who can vote on their behalf via [`setDelegate()`](#setDelegate).
19-
*
19+
*
2020
* To cast a vote, either the voter or their delegate can call [`vote()`](#vote) or [`voteMultiple()`](#voteMultiple).
2121
* Votes can be cast among existing gaugeIDs (set in GaugeController.sol), and voters/delegates can set a custom proportion
2222
* of their total voting power for different gauges.
2323
* Voting power proportion is measured in bps, and total used voting power bps for a voter cannot exceed 10000.
24-
*
24+
*
2525
* Votes are saved, so a vote today will count as the voter's vote for all future epochs until the voter modifies their votes.
26-
*
26+
*
2727
* After each epoch (one-week) has passed, voting is frozen until governance has processed all the votes.
2828
* This is a two-step process:
2929
* GaugeController.updateGaugeWeights() - this will aggregate individual votes and update gauge weights accordingly
30-
* [`chargePremiums()`](#chargepremiums) - this will charge premiums for every vote. There is a voting premium
30+
* [`chargePremiums()`](#chargepremiums) - this will charge premiums for every vote. There is a voting premium
3131
* to be paid every epoch, this gets sent to the revenue router.
3232
*/
3333
interface IUnderwritingLockVoting is IGaugeVoter {
@@ -187,7 +187,7 @@ interface IUnderwritingLockVoting is IGaugeVoter {
187187

188188
/**
189189
* @notice Register a single vote for a gauge. Can either add or change a vote.
190-
* @notice Can also remove a vote (votePowerBPS_ == 0), the difference with removeVote() is that
190+
* @notice Can also remove a vote (votePowerBPS_ == 0), the difference with removeVote() is that
191191
* vote() will revert if the voter has no locks (no locks => no right to vote, but may have votes from
192192
* locks that have since been burned).
193193
* @notice GaugeController.updateGaugeWeights() will remove voters with no voting power, however voters can

contracts/interfaces/native/IUnderwritingLocker.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ struct Lock {
1414
* @author solace.fi
1515
* @notice Having an underwriting lock is a requirement to vote on Solace Native insurance gauges.
1616
* To create an underwriting lock, $UWE must be locked for a minimum of 6 months.
17-
*
18-
* Locks are ERC721s and can be viewed with [`locks()`](#locks).
17+
*
18+
* Locks are ERC721s and can be viewed with [`locks()`](#locks).
1919
* Each lock has an `amount` of locked $UWE, and an `end` timestamp.
2020
* Locks have a maximum duration of four years.
2121
*

contracts/native/BribeController.sol

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import "./../interfaces/native/IGaugeController.sol";
1111
import "./../interfaces/utils/IRegistry.sol";
1212
import "./../utils/EnumerableMapS.sol";
1313
import "./../utils/Governable.sol";
14-
import "hardhat/console.sol";
1514

1615
contract BribeController is
1716
IBribeController,

contracts/native/DepositHelper.sol

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,14 @@ contract DepositHelper is IDepositHelper, ReentrancyGuard {
2828
STATE VARIABLES
2929
***************************************/
3030

31-
address internal _uwp;
3231
address internal _uwe;
3332
address internal _locker;
3433

35-
constructor(address uwp_, address uwe_, address locker_) {
36-
require(uwp_ != address(0x0), "zero address uwp");
34+
constructor(address uwe_, address locker_) {
3735
require(uwe_ != address(0x0), "zero address uwe");
3836
require(locker_ != address(0x0), "zero address locker");
39-
_uwp = uwp_;
4037
_uwe = uwe_;
4138
_locker = locker_;
42-
IERC20(uwp_).approve(uwe_, type(uint256).max);
4339
IERC20(uwe_).approve(locker_, type(uint256).max);
4440
}
4541

@@ -52,7 +48,7 @@ contract DepositHelper is IDepositHelper, ReentrancyGuard {
5248
* @return uwp The underwriting pool.
5349
*/
5450
function underwritingPool() external view override returns (address uwp) {
55-
return _uwp;
51+
return IUnderwritingEquity(_uwe).underwritingPool();
5652
}
5753

5854
/**
@@ -79,8 +75,8 @@ contract DepositHelper is IDepositHelper, ReentrancyGuard {
7975
* @return uweAmount The amount of [`UWE`](./UnderwritingEquity) that will be minted to the receiver.
8076
*/
8177
function calculateDeposit(address depositToken, uint256 depositAmount) external view override returns (uint256 uweAmount) {
82-
address uwp_ = _uwp;
8378
address uwe_ = _uwe;
79+
address uwp_ = IUnderwritingEquity(uwe_).underwritingPool();
8480
uint256 amount = depositAmount;
8581
// if deposit token is not uwp nor uwe
8682
// likely token is member of set
@@ -154,8 +150,8 @@ contract DepositHelper is IDepositHelper, ReentrancyGuard {
154150
address depositToken,
155151
uint256 depositAmount
156152
) internal returns (uint256 uweAmount) {
157-
address uwp_ = _uwp;
158153
address uwe_ = _uwe;
154+
address uwp_ = IUnderwritingEquity(uwe_).underwritingPool();
159155
uint256 amount = depositAmount;
160156
IERC20 tkn = IERC20(depositToken);
161157
// pull tokens from msg.sender
@@ -174,6 +170,8 @@ contract DepositHelper is IDepositHelper, ReentrancyGuard {
174170
// if deposit token is not uwe
175171
if(depositToken != uwe_) {
176172
// deposit uwp into uwe
173+
IERC20 uwp2 = IERC20(uwp_);
174+
if(uwp2.allowance(address(this), uwe_) < amount) uwp2.approve(uwe_, type(uint256).max);
177175
amount = IUnderwritingEquity(uwe_).deposit(amount, address(this));
178176
}
179177
return amount;

contracts/native/GaugeController.sol

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@ import "./../interfaces/native/IGaugeController.sol";
1818
* Current gauge weights can be obtained through [`getGaugeWeight()`](#getgaugeweight) and [`getAllGaugeWeights()`](#getallgaugeweights)
1919
*
2020
* Only governance can make mutator calls to GaugeController.sol. There are no unpermissioned external mutator calls in this contract.
21-
*
21+
*
2222
* After every epoch, governance must call [`updateGaugeWeights()`](#updategaugeweights). This will process the last epoch's votes (stored in this contract).
23-
*
23+
*
2424
* Individual voters register and manage their vote through voting contracts that conform to IGaugeVoting.
2525
*
2626
* Governance can [`addGauge()`](#addgauge) or [`pauseGauge()`](#pausegauge).
2727
*/
2828
// solhint-disable-next-line contract-name-camelcase
29-
contract GaugeController is
30-
IGaugeController,
31-
ReentrancyGuard,
32-
Governable
29+
contract GaugeController is
30+
IGaugeController,
31+
ReentrancyGuard,
32+
Governable
3333
{
3434
using EnumerableSet for EnumerableSet.AddressSet;
3535
using EnumerableMapS for EnumerableMapS.UintToUintMap;
@@ -296,7 +296,7 @@ contract GaugeController is
296296
(uint256 gaugeID, uint256 votingPowerBPS) = _votes[votingContract_][voter_].at(i);
297297
votes[i] = GaugeStructs.Vote(gaugeID, votingPowerBPS);
298298
}
299-
}
299+
}
300300
}
301301

302302
/**
@@ -313,7 +313,7 @@ contract GaugeController is
313313
for (uint256 i = 0; i < votersCount; i++) {
314314
voters[i] = _voters[votingContract_].at(i);
315315
}
316-
}
316+
}
317317
}
318318

319319
/**
@@ -327,7 +327,7 @@ contract GaugeController is
327327
return 0;
328328
} else {
329329
return _votes[votingContract_][voter_].length();
330-
}
330+
}
331331
}
332332

333333
/**
@@ -340,7 +340,7 @@ contract GaugeController is
340340
return 0;
341341
} else {
342342
return _voters[votingContract_].length();
343-
}
343+
}
344344
}
345345

346346
/**
@@ -350,7 +350,7 @@ contract GaugeController is
350350
function getEpochLength() external view override returns (uint256 epochLength) {
351351
return _epochLength;
352352
}
353-
353+
354354
/***************************************
355355
INTERNAL MUTATOR FUNCTIONS
356356
***************************************/
@@ -376,14 +376,14 @@ contract GaugeController is
376376
return 0;
377377
// Else if removing vote
378378
} else if (newVotePowerBPS_ == 0) {
379-
uint256 oldVotePowerBPS = _votes[votingContract_][voter_].get(gaugeID_);
379+
oldVotePowerBPS = _votes[votingContract_][voter_].get(gaugeID_);
380380
_votes[votingContract_][voter_].remove(gaugeID_);
381381
// Check if need to remove voter
382382
if ( _votes[votingContract_][voter_].length() == 0 ) {_voters[votingContract_].remove(voter_);}
383383
return oldVotePowerBPS;
384384
// Else modify vote
385385
} else {
386-
uint256 oldVotePowerBPS = _votes[votingContract_][voter_].get(gaugeID_);
386+
oldVotePowerBPS = _votes[votingContract_][voter_].get(gaugeID_);
387387
_votes[votingContract_][voter_].set(gaugeID_, newVotePowerBPS_);
388388
return oldVotePowerBPS;
389389
}
@@ -445,7 +445,7 @@ contract GaugeController is
445445
function addGauge(string calldata gaugeName_, uint256 rateOnLine_) external override onlyGovernance {
446446
uint256 gaugeID = ++totalGauges;
447447
GaugeStructs.Gauge memory newGauge = GaugeStructs.Gauge(true, SafeCastS.toUint248(rateOnLine_), gaugeName_);
448-
_gauges.push(newGauge);
448+
_gauges.push(newGauge);
449449
assert(_gauges.length - 1 == totalGauges); // Uphold invariant, should not be violated. -1 because we already added _gauges[0] in constructor.
450450
emit GaugeAdded(gaugeID, rateOnLine_, gaugeName_);
451451
}
@@ -572,7 +572,7 @@ contract GaugeController is
572572
for(uint256 j = _updateInfo.index2 == type(uint88).max || i != _updateInfo.index1 ? 0 : _updateInfo.index2 ; j < numVoters; j++) {
573573
if (gasleft() < 200000) {return _saveUpdateState(i, j, 0);}
574574
address voter = _voters[votingContract].at(j);
575-
uint256 numVotes = _votes[votingContract][voter].length();
575+
uint256 numVotes = _votes[votingContract][voter].length();
576576
uint256 votePower = IGaugeVoter(votingContract).getVotePower(voter); // Expensive computation here. ~150K gas for user with max cap of 10 locks.
577577
if (votePower == 0) {
578578
_votersToRemove.push(voter);
@@ -602,7 +602,7 @@ contract GaugeController is
602602
_votersToRemove.pop();
603603
}
604604
}
605-
605+
606606
_adjustVotePowerOfGaugeMapping();
607607
_clearUpdateInfo();
608608
lastTimeGaugeWeightsUpdated = epochStartTime;
@@ -625,7 +625,7 @@ contract GaugeController is
625625
updateInfo := or(updateInfo, shr(176, shl(176, votingContractsIndex_))) // [0:80] => votingContractsIndex_
626626
updateInfo := or(updateInfo, shr(88, shl(168, votersIndex_))) // [80:168] => votersIndex_
627627
updateInfo := or(updateInfo, shl(168, votesIndex_)) // [168:256] => votesIndex_
628-
sstore(_updateInfo.slot, updateInfo)
628+
sstore(_updateInfo.slot, updateInfo)
629629
}
630630
emit IncompleteGaugeUpdate();
631631
}
@@ -655,4 +655,4 @@ contract GaugeController is
655655
}
656656
}
657657
}
658-
}
658+
}

contracts/native/UnderwritingEquity.sol

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ contract UnderwritingEquity is IUnderwritingEquity, ERC20Permit, ReentrancyGuard
247247

248248
/**
249249
* @notice Pauses or unpauses contract functionality.
250+
* Can only be called by the current [**governor**](/docs/protocol/governance).
250251
* @param depositIsPaused True to pause deposit, false to unpause.
251252
* @param withdrawIsPaused True to pause withdraw, false to unpause.
252253
* @param lendIsPaused True to pause lend, false to unpause.
@@ -257,4 +258,15 @@ contract UnderwritingEquity is IUnderwritingEquity, ERC20Permit, ReentrancyGuard
257258
_lendIsPaused = lendIsPaused;
258259
emit PauseSet(depositIsPaused, withdrawIsPaused, lendIsPaused);
259260
}
261+
262+
/**
263+
* @notice Upgrades the [`UWP`](./UnderwritingPool) contract.
264+
* Can only be called by the current [**governor**](/docs/protocol/governance).
265+
* @param uwp_ The address of the new [`UWP`](./UnderwritingPool).
266+
*/
267+
function setUwp(address uwp_) external override onlyGovernance {
268+
require(uwp_ != address(0x0), "zero address uwp");
269+
_uwp = uwp_;
270+
emit UwpSet(uwp_);
271+
}
260272
}

0 commit comments

Comments
 (0)