Skip to content

Commit 6517aee

Browse files
MikeHathawayMike
and
Mike
authored
625 feedback (#659)
* initial implementation of increase/decrease allowance * update tests for increase/decrease * remove unused function * update comments * rename lp transfer event * additional assertions * remove msg.sender param from ApproveLPTransfer * rename events --------- Co-authored-by: Mike <mikehathaway@makerdao.com>
1 parent ce21e3f commit 6517aee

9 files changed

+245
-71
lines changed

src/PositionManager.sol

+2-2
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ contract PositionManager is ERC721, PermitERC721, IPositionManager, Multicall, R
317317
/**
318318
* @inheritdoc IPositionManagerOwnerActions
319319
* @dev External calls to Pool contract:
320-
* - approveLpOwnership(): approve ownership for transfer
320+
* - increaseLPAllowance(): approve ownership for transfer
321321
* - transferLPs(): transfer LPs ownership from PositionManager contract
322322
* @dev write state:
323323
* - positionIndexes: remove from bucket index
@@ -367,7 +367,7 @@ contract PositionManager is ERC721, PermitERC721, IPositionManager, Multicall, R
367367
address owner = ownerOf(params_.tokenId);
368368

369369
// approve owner to take over the LPs ownership (required for transferLPs pool call)
370-
pool.approveLpOwnership(owner, params_.indexes, lpAmounts);
370+
pool.increaseLPAllowance(owner, params_.indexes, lpAmounts);
371371
// update pool lps accounting and transfer ownership of lps from PositionManager contract
372372
pool.transferLPs(address(this), owner, params_.indexes);
373373

src/base/Pool.sol

+65-15
Original file line numberDiff line numberDiff line change
@@ -164,41 +164,82 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
164164
_transferQuoteTokenFrom(msg.sender, quoteTokenAmountToAdd_);
165165
}
166166

167-
/**
168-
* @inheritdoc IPoolLenderActions
169-
* @dev write state:
170-
* - _lpAllowances mapping
171-
*/
172-
function approveLpOwnership(
173-
address newOwner_,
167+
/// @inheritdoc IPoolLenderActions
168+
function decreaseLPAllowance(
169+
address spender_,
174170
uint256[] calldata indexes_,
175171
uint256[] calldata amounts_
176172
) external override nonReentrant {
177-
mapping(uint256 => uint256) storage allowances = _lpAllowances[msg.sender][newOwner_];
173+
mapping(uint256 => uint256) storage allowances = _lpAllowances[msg.sender][spender_];
178174

179175
uint256 indexesLength = indexes_.length;
180176
uint256 index;
181177

182178
for (uint256 i = 0; i < indexesLength; ) {
183179
index = indexes_[i];
184180

185-
// revert if allowance at index is already set (not 0) and the new allowance does not reset the old one (not 0)
186-
// this prevents possible attack where LPs receiver (newOwner) frontruns owner allowance calls to transfer more than allowed
187-
if (allowances[index] != 0 && amounts_[i] != 0) revert AllowanceAlreadySet();
181+
allowances[index] -= amounts_[i];
182+
183+
unchecked { ++i; }
184+
}
185+
186+
emit SetLpAllowance(
187+
spender_,
188+
indexes_,
189+
amounts_
190+
);
191+
}
192+
193+
/// @inheritdoc IPoolLenderActions
194+
function increaseLPAllowance(
195+
address spender_,
196+
uint256[] calldata indexes_,
197+
uint256[] calldata amounts_
198+
) external override nonReentrant {
199+
mapping(uint256 => uint256) storage allowances = _lpAllowances[msg.sender][spender_];
200+
201+
uint256 indexesLength = indexes_.length;
202+
uint256 index;
203+
204+
for (uint256 i = 0; i < indexesLength; ) {
205+
index = indexes_[i];
188206

189-
allowances[index] = amounts_[i];
207+
allowances[index] += amounts_[i];
190208

191209
unchecked { ++i; }
192210
}
193211

194-
emit ApproveLpOwnership(
195-
msg.sender,
196-
newOwner_,
212+
emit SetLpAllowance(
213+
spender_,
197214
indexes_,
198215
amounts_
199216
);
200217
}
201218

219+
/// @inheritdoc IPoolLenderActions
220+
function revokeLPAllowance(
221+
address spender_,
222+
uint256[] calldata indexes_
223+
) external override nonReentrant {
224+
mapping(uint256 => uint256) storage allowances = _lpAllowances[msg.sender][spender_];
225+
226+
uint256 indexesLength = indexes_.length;
227+
uint256 index;
228+
229+
for (uint256 i = 0; i < indexesLength; ) {
230+
index = indexes_[i];
231+
232+
allowances[index] = 0;
233+
234+
unchecked { ++i; }
235+
}
236+
237+
emit RevokeLpAllowance(
238+
spender_,
239+
indexes_
240+
);
241+
}
242+
202243
/**
203244
* @inheritdoc IPoolLenderActions
204245
* @dev write state:
@@ -822,6 +863,15 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool {
822863
if (buckets[index_].bankruptcyTime < depositTime_) lpBalance_ = buckets[index_].lenders[lender_].lps;
823864
}
824865

866+
/// @inheritdoc IPoolState
867+
function lpAllowance(
868+
uint256 index_,
869+
address spender_,
870+
address owner_
871+
) external view override returns (uint256 allowance_) {
872+
allowance_ = _lpAllowances[owner_][spender_][index_];
873+
}
874+
825875
/// @inheritdoc IPoolState
826876
function loanInfo(
827877
uint256 loanId_

src/interfaces/pool/commons/IPoolEvents.sol

+14-6
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,13 @@ interface IPoolEvents {
2323
);
2424

2525
/**
26-
* @notice Emitted when lender approves a new owner of LPs at specified indexes with specified amounts.
27-
* @param lender Recipient that approves new owner for LPs.
28-
* @param newOwner Recipient approved to transfer LPs.
26+
* @notice Emitted when lender approves a spender owner of LPs at specified indexes with specified amounts.
27+
* @param spender Address approved to transfer LPs.
2928
* @param indexes Bucket indexes of LPs approved.
3029
* @param amounts LP amounts approved (ordered by approved indexes).
3130
*/
32-
event ApproveLpOwnership(
33-
address indexed lender,
34-
address indexed newOwner,
31+
event SetLpAllowance(
32+
address indexed spender,
3533
uint256[] indexes,
3634
uint256[] amounts
3735
);
@@ -234,6 +232,16 @@ interface IPoolEvents {
234232
uint256 currentBurnEpoch
235233
);
236234

235+
/**
236+
* @notice Emitted when lender removes the allowance of a spender for their LPB.
237+
* @param spender Address that is having it's allowance revoked.
238+
* @param indexes List of bucket index to remove the allowance from.
239+
*/
240+
event RevokeLpAllowance(
241+
address indexed spender,
242+
uint256[] indexes
243+
);
244+
237245
/**
238246
* @notice Emitted when lender removes addresses from the LPs transferors whitelist.
239247
* @param lender Recipient that approves new owner for LPs.

src/interfaces/pool/commons/IPoolLenderActions.sol

+27-4
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,27 @@ interface IPoolLenderActions {
2020
) external returns (uint256 lpbChange);
2121

2222
/**
23-
* @notice Called by lenders to approve transfer of LPs to a new owner.
23+
* @notice Called by lenders to approve transfer of an amount of LPs to a new owner.
2424
* @dev Intended for use by the PositionManager contract.
25-
* @param allowedNewOwner The new owner of the LPs.
25+
* @param spender The new owner of the LPs.
2626
* @param indexes Bucket indexes from where LPs are transferred.
2727
* @param amounts The amounts of LPs approved to transfer.
2828
*/
29-
function approveLpOwnership(
30-
address allowedNewOwner,
29+
function increaseLPAllowance(
30+
address spender,
31+
uint256[] calldata indexes,
32+
uint256[] calldata amounts
33+
) external;
34+
35+
/**
36+
* @notice Called by lenders to decrease the amount of LPs that can be spend by a new owner.
37+
* @dev Intended for use by the PositionManager contract.
38+
* @param spender The new owner of the LPs.
39+
* @param indexes Bucket indexes from where LPs are transferred.
40+
* @param amounts The amounts of LPs approved to transfer.
41+
*/
42+
function decreaseLPAllowance(
43+
address spender,
3144
uint256[] calldata indexes,
3245
uint256[] calldata amounts
3346
) external;
@@ -91,6 +104,16 @@ interface IPoolLenderActions {
91104
uint256 index
92105
) external returns (uint256 quoteTokenAmount, uint256 lpAmount);
93106

107+
/**
108+
* @notice Called by lenders to decrease the amount of LPs that can be spend by a new owner.
109+
* @param spender Address that is having it's allowance revoked.
110+
* @param indexes List of bucket index to remove the allowance from.
111+
*/
112+
function revokeLPAllowance(
113+
address spender,
114+
uint256[] calldata indexes
115+
) external;
116+
94117
/**
95118
* @notice Called by lenders to transfers their LPs to a different address. approveLpOwnership needs to be run first
96119
* @dev Used by PositionManager.memorializePositions().

src/interfaces/pool/commons/IPoolState.sol

+13
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,19 @@ interface IPoolState {
176176
uint256 lastQuoteDeposit
177177
);
178178

179+
/**
180+
* @notice Return the LPB allowance a LP owner provided to a spender.
181+
* @param index Bucket index.
182+
* @param spender Address of the LPB spender.
183+
* @param owner The initial owner of the LPs.
184+
* @return allowance_ Amount of LPs spender can utilize.
185+
*/
186+
function lpAllowance(
187+
uint256 index,
188+
address spender,
189+
address owner
190+
) external view returns (uint256 allowance_);
191+
179192
/**
180193
* @notice Returns information about a loan in the pool.
181194
* @param loanId Loan's id within loan heap. Max loan is position 1.

0 commit comments

Comments
 (0)