Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions snapshots/NativeTokenGateway.Operations.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"borrowNative": "229316",
"repayNative": "168024",
"supplyAsCollateralNative": "160373",
"supplyNative": "136476",
"withdrawNative: full": "125620",
"withdrawNative: partial": "136825"
"borrowNative": "229372",
"repayNative": "161657",
"supplyAsCollateralNative": "154110",
"supplyNative": "124476",
"withdrawNative: full": "125648",
"withdrawNative: partial": "136859"
}
16 changes: 8 additions & 8 deletions snapshots/SignatureGateway.Operations.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"borrowWithSig": "215605",
"repayWithSig": "188872",
"setSelfAsUserPositionManagerWithSig": "75402",
"setUsingAsCollateralWithSig": "85053",
"supplyWithSig": "153205",
"updateUserDynamicConfigWithSig": "62769",
"updateUserRiskPremiumWithSig": "61579",
"withdrawWithSig": "131696"
"borrowWithSig": "215661",
"repayWithSig": "188919",
"setSelfAsUserPositionManagerWithSig": "75424",
"setUsingAsCollateralWithSig": "85109",
"supplyWithSig": "153262",
"updateUserDynamicConfigWithSig": "62791",
"updateUserRiskPremiumWithSig": "61601",
"withdrawWithSig": "131723"
}
10 changes: 5 additions & 5 deletions snapshots/Spoke.Getters.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"getUserAccountData: supplies: 0, borrows: 0": "11937",
"getUserAccountData: supplies: 1, borrows: 0": "48600",
"getUserAccountData: supplies: 2, borrows: 0": "80378",
"getUserAccountData: supplies: 2, borrows: 1": "100166",
"getUserAccountData: supplies: 2, borrows: 2": "118596"
"getUserAccountData: supplies: 0, borrows: 0": "11959",
"getUserAccountData: supplies: 1, borrows: 0": "48622",
"getUserAccountData: supplies: 2, borrows: 0": "80400",
"getUserAccountData: supplies: 2, borrows: 1": "100188",
"getUserAccountData: supplies: 2, borrows: 2": "118618"
}
62 changes: 31 additions & 31 deletions snapshots/Spoke.Operations.ZeroRiskPremium.json
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
{
"borrow: first": "191325",
"borrow: second action, same reserve": "171297",
"liquidationCall (receiveShares): full": "300103",
"liquidationCall (receiveShares): partial": "299821",
"liquidationCall: full": "310468",
"liquidationCall: partial": "310186",
"permitReserve + repay (multicall)": "166029",
"permitReserve + supply (multicall)": "146862",
"permitReserve + supply + enable collateral (multicall)": "160573",
"repay: full": "126094",
"repay: partial": "130983",
"setUserPositionManagerWithSig: disable": "44846",
"setUserPositionManagerWithSig: enable": "68875",
"supply + enable collateral (multicall)": "140624",
"supply: 0 borrows, collateral disabled": "123679",
"supply: 0 borrows, collateral enabled": "106601",
"supply: second action, same reserve": "106579",
"updateUserDynamicConfig: 1 collateral": "73694",
"updateUserDynamicConfig: 2 collaterals": "88551",
"updateUserRiskPremium: 1 borrow": "94804",
"updateUserRiskPremium: 2 borrows": "104619",
"usingAsCollateral: 0 borrows, enable": "58915",
"usingAsCollateral: 1 borrow, disable": "105072",
"usingAsCollateral: 1 borrow, enable": "41803",
"usingAsCollateral: 2 borrows, disable": "126055",
"usingAsCollateral: 2 borrows, enable": "41815",
"withdraw: 0 borrows, full": "128910",
"withdraw: 0 borrows, partial": "133473",
"withdraw: 1 borrow, partial": "161036",
"withdraw: 2 borrows, partial": "174214",
"withdraw: non collateral": "106544"
"borrow: first": "191381",
"borrow: second action, same reserve": "171353",
"liquidationCall (receiveShares): full": "300125",
"liquidationCall (receiveShares): partial": "299843",
"liquidationCall: full": "310490",
"liquidationCall: partial": "310208",
"permitReserve + repay (multicall)": "166099",
"permitReserve + supply (multicall)": "146868",
"permitReserve + supply + enable collateral (multicall)": "160635",
"repay: full": "126229",
"repay: partial": "131118",
"setUserPositionManagerWithSig: disable": "44868",
"setUserPositionManagerWithSig: enable": "68897",
"supply + enable collateral (multicall)": "140686",
"supply: 0 borrows, collateral disabled": "123750",
"supply: 0 borrows, collateral enabled": "106672",
"supply: second action, same reserve": "106650",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls add skim version of those snapshots

"updateUserDynamicConfig: 1 collateral": "73716",
"updateUserDynamicConfig: 2 collaterals": "88573",
"updateUserRiskPremium: 1 borrow": "94826",
"updateUserRiskPremium: 2 borrows": "104641",
"usingAsCollateral: 0 borrows, enable": "58971",
"usingAsCollateral: 1 borrow, disable": "105128",
"usingAsCollateral: 1 borrow, enable": "41859",
"usingAsCollateral: 2 borrows, disable": "126111",
"usingAsCollateral: 2 borrows, enable": "41871",
"withdraw: 0 borrows, full": "128944",
"withdraw: 0 borrows, partial": "133507",
"withdraw: 1 borrow, partial": "161070",
"withdraw: 2 borrows, partial": "174248",
"withdraw: non collateral": "106578"
}
62 changes: 31 additions & 31 deletions snapshots/Spoke.Operations.json
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
{
"borrow: first": "261721",
"borrow: second action, same reserve": "204693",
"liquidationCall (receiveShares): full": "333666",
"liquidationCall (receiveShares): partial": "333384",
"liquidationCall: full": "344031",
"liquidationCall: partial": "343749",
"permitReserve + repay (multicall)": "163273",
"permitReserve + supply (multicall)": "146862",
"permitReserve + supply + enable collateral (multicall)": "160573",
"repay: full": "120256",
"repay: partial": "139545",
"setUserPositionManagerWithSig: disable": "44846",
"setUserPositionManagerWithSig: enable": "68875",
"supply + enable collateral (multicall)": "140624",
"supply: 0 borrows, collateral disabled": "123679",
"supply: 0 borrows, collateral enabled": "106601",
"supply: second action, same reserve": "106579",
"updateUserDynamicConfig: 1 collateral": "73694",
"updateUserDynamicConfig: 2 collaterals": "88551",
"updateUserRiskPremium: 1 borrow": "151080",
"updateUserRiskPremium: 2 borrows": "204276",
"usingAsCollateral: 0 borrows, enable": "58915",
"usingAsCollateral: 1 borrow, disable": "161348",
"usingAsCollateral: 1 borrow, enable": "41803",
"usingAsCollateral: 2 borrows, disable": "233712",
"usingAsCollateral: 2 borrows, enable": "41815",
"withdraw: 0 borrows, full": "128910",
"withdraw: 0 borrows, partial": "133473",
"withdraw: 1 borrow, partial": "214810",
"withdraw: 2 borrows, partial": "259272",
"withdraw: non collateral": "106544"
"borrow: first": "261777",
"borrow: second action, same reserve": "204749",
"liquidationCall (receiveShares): full": "333688",
"liquidationCall (receiveShares): partial": "333406",
"liquidationCall: full": "344053",
"liquidationCall: partial": "343771",
"permitReserve + repay (multicall)": "163329",
"permitReserve + supply (multicall)": "146868",
"permitReserve + supply + enable collateral (multicall)": "160635",
"repay: full": "120391",
"repay: partial": "139680",
"setUserPositionManagerWithSig: disable": "44868",
"setUserPositionManagerWithSig: enable": "68897",
"supply + enable collateral (multicall)": "140686",
"supply: 0 borrows, collateral disabled": "123750",
"supply: 0 borrows, collateral enabled": "106672",
"supply: second action, same reserve": "106650",
"updateUserDynamicConfig: 1 collateral": "73716",
"updateUserDynamicConfig: 2 collaterals": "88573",
"updateUserRiskPremium: 1 borrow": "151102",
"updateUserRiskPremium: 2 borrows": "204298",
"usingAsCollateral: 0 borrows, enable": "58971",
"usingAsCollateral: 1 borrow, disable": "161404",
"usingAsCollateral: 1 borrow, enable": "41859",
"usingAsCollateral: 2 borrows, disable": "233768",
"usingAsCollateral: 2 borrows, enable": "41871",
"withdraw: 0 borrows, full": "128944",
"withdraw: 0 borrows, partial": "133507",
"withdraw: 1 borrow, partial": "214844",
"withdraw: 2 borrows, partial": "259306",
"withdraw: non collateral": "106578"
}
8 changes: 8 additions & 0 deletions src/position-manager/GatewayBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ abstract contract GatewayBase is IGatewayBase, Rescuable, Ownable2Step {
return ISpoke(spoke).getReserve(reserveId).underlying;
}

function _getReserveInfo(
address spoke,
uint256 reserveId
) internal view returns (address hub, address underlying) {
ISpoke.Reserve memory reserve = ISpoke(spoke).getReserve(reserveId);
return (address(reserve.hub), address(reserve.underlying));
}

/// @dev The `owner()` is the allowed caller for Rescuable methods.
function _rescueGuardian() internal view override returns (address) {
return owner();
Expand Down
12 changes: 6 additions & 6 deletions src/position-manager/NativeTokenGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ contract NativeTokenGateway is INativeTokenGateway, GatewayBase, ReentrancyGuard
uint256 amount
) external payable nonReentrant onlyRegisteredSpoke(spoke) returns (uint256, uint256) {
require(msg.value == amount, NativeAmountMismatch());
address underlying = _getReserveUnderlying(spoke, reserveId);
(address hub, address underlying) = _getReserveInfo(spoke, reserveId);
_validateParams(underlying, amount);

uint256 userTotalDebt = ISpoke(spoke).getUserTotalDebt(reserveId, msg.sender);
Expand All @@ -124,8 +124,8 @@ contract NativeTokenGateway is INativeTokenGateway, GatewayBase, ReentrancyGuard
}

_nativeWrapper.deposit{value: repayAmount}();
_nativeWrapper.forceApprove(spoke, repayAmount);
(uint256 repaidShares, uint256 repaidAmount) = ISpoke(spoke).repay(
_nativeWrapper.safeTransfer(hub, repayAmount);
(uint256 repaidShares, uint256 repaidAmount) = ISpoke(spoke).repaySkimmed(
reserveId,
repayAmount,
msg.sender
Expand All @@ -150,12 +150,12 @@ contract NativeTokenGateway is INativeTokenGateway, GatewayBase, ReentrancyGuard
address user,
uint256 amount
) internal returns (uint256, uint256) {
address underlying = _getReserveUnderlying(spoke, reserveId);
(address hub, address underlying) = _getReserveInfo(spoke, reserveId);
_validateParams(underlying, amount);

_nativeWrapper.deposit{value: amount}();
_nativeWrapper.forceApprove(spoke, amount);
return ISpoke(spoke).supply(reserveId, amount, user);
_nativeWrapper.safeTransfer(hub, amount);
return ISpoke(spoke).supplySkimmed(reserveId, amount, user);
}

function _validateParams(address underlying, uint256 amount) internal view {
Expand Down
132 changes: 88 additions & 44 deletions src/spoke/Spoke.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ abstract contract Spoke is ISpoke, Multicall, NoncesKeyed, AccessManagedUpgradea

/// @notice Modifier that checks if the caller is an approved positionManager for `onBehalfOf`.
modifier onlyPositionManager(address onBehalfOf) {
require(_isPositionManager({user: onBehalfOf, manager: msg.sender}), Unauthorized());
_onlyPositionManager({onBehalfOf: onBehalfOf, caller: msg.sender});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code size hack ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah jump instead of inlining but think compiler was already doing it

_;
}

Expand Down Expand Up @@ -232,17 +232,16 @@ abstract contract Spoke is ISpoke, Multicall, NoncesKeyed, AccessManagedUpgradea
uint256 amount,
address onBehalfOf
) external onlyPositionManager(onBehalfOf) returns (uint256, uint256) {
Reserve storage reserve = _getReserve(reserveId);
UserPosition storage userPosition = _userPositions[onBehalfOf][reserveId];
_validateSupply(reserve.flags);

IERC20(reserve.underlying).safeTransferFrom(msg.sender, address(reserve.hub), amount);
uint256 suppliedShares = reserve.hub.add(reserve.assetId, amount);
userPosition.suppliedShares += suppliedShares.toUint120();

emit Supply(reserveId, msg.sender, onBehalfOf, suppliedShares, amount);
return _supply(reserveId, amount, onBehalfOf, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for both supply and repay, since the transfer caller -> hub does not impact calculations if made earlier than in current logic, might be interesting to do the transfer before calling the internal function, so we don't need to pass a true/false arg & perform an extra if check

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and would allow to revert earlier if no allowance given.

And with the nonReentrant guards we want to add to those functions, this behavior should be safe enough, wdyt ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice one! yeah it just increases the diff, mainly on restore since we need to cap transferred amount to max debt and wanted to avoid this complexity

}

return (suppliedShares, amount);
/// @inheritdoc ISpokeBase
function supplySkimmed(
uint256 reserveId,
uint256 amount,
address onBehalfOf
) external onlyPositionManager(onBehalfOf) returns (uint256, uint256) {
return _supply(reserveId, amount, onBehalfOf, true);
}

/// @inheritdoc ISpokeBase
Expand Down Expand Up @@ -307,40 +306,16 @@ abstract contract Spoke is ISpoke, Multicall, NoncesKeyed, AccessManagedUpgradea
uint256 amount,
address onBehalfOf
) external onlyPositionManager(onBehalfOf) returns (uint256, uint256) {
Reserve storage reserve = _getReserve(reserveId);
UserPosition storage userPosition = _userPositions[onBehalfOf][reserveId];
_validateRepay(reserve.flags);

uint256 drawnIndex = reserve.hub.getAssetDrawnIndex(reserve.assetId);
(uint256 drawnDebtRestored, uint256 premiumDebtRayRestored) = userPosition
.calculateRestoreAmount(drawnIndex, amount);
uint256 restoredShares = drawnDebtRestored.rayDivDown(drawnIndex);

IHubBase.PremiumDelta memory premiumDelta = userPosition.getPremiumDelta({
drawnSharesTaken: restoredShares,
drawnIndex: drawnIndex,
riskPremium: _positionStatus[onBehalfOf].riskPremium,
restoredPremiumRay: premiumDebtRayRestored
});

uint256 totalDebtRestored = drawnDebtRestored + premiumDebtRayRestored.fromRayUp();
IERC20(reserve.underlying).safeTransferFrom(
msg.sender,
address(reserve.hub),
totalDebtRestored
);
reserve.hub.restore(reserve.assetId, drawnDebtRestored, premiumDelta);

userPosition.applyPremiumDelta(premiumDelta);
userPosition.drawnShares -= restoredShares.toUint120();
if (userPosition.drawnShares == 0) {
PositionStatus storage positionStatus = _positionStatus[onBehalfOf];
positionStatus.setBorrowing(reserveId, false);
}

emit Repay(reserveId, msg.sender, onBehalfOf, restoredShares, totalDebtRestored, premiumDelta);
return _repay(reserveId, amount, onBehalfOf, false);
}

return (restoredShares, totalDebtRestored);
/// @inheritdoc ISpokeBase
function repaySkimmed(
uint256 reserveId,
uint256 amount,
address onBehalfOf
) external onlyPositionManager(onBehalfOf) returns (uint256, uint256) {
return _repay(reserveId, amount, onBehalfOf, true);
}

/// @inheritdoc ISpokeBase
Expand Down Expand Up @@ -890,6 +865,71 @@ abstract contract Spoke is ISpoke, Multicall, NoncesKeyed, AccessManagedUpgradea
}
}

function _supply(
uint256 reserveId,
uint256 amount,
address onBehalfOf,
bool skim
) internal returns (uint256, uint256) {
Reserve storage reserve = _getReserve(reserveId);
UserPosition storage userPosition = _userPositions[onBehalfOf][reserveId];
_validateSupply(reserve.flags);

if (!skim) {
IERC20(reserve.underlying).safeTransferFrom(msg.sender, address(reserve.hub), amount);
}
uint256 suppliedShares = reserve.hub.add(reserve.assetId, amount);
userPosition.suppliedShares += suppliedShares.toUint120();

emit Supply(reserveId, msg.sender, onBehalfOf, suppliedShares, amount);

return (suppliedShares, amount);
}

function _repay(
uint256 reserveId,
uint256 amount,
address onBehalfOf,
bool skim
) internal returns (uint256, uint256) {
Reserve storage reserve = _getReserve(reserveId);
UserPosition storage userPosition = _userPositions[onBehalfOf][reserveId];
_validateRepay(reserve.flags);

uint256 drawnIndex = reserve.hub.getAssetDrawnIndex(reserve.assetId);
(uint256 drawnDebtRestored, uint256 premiumDebtRayRestored) = userPosition
.calculateRestoreAmount(drawnIndex, amount);
uint256 restoredShares = drawnDebtRestored.rayDivDown(drawnIndex);

IHubBase.PremiumDelta memory premiumDelta = userPosition.getPremiumDelta({
drawnSharesTaken: restoredShares,
drawnIndex: drawnIndex,
riskPremium: _positionStatus[onBehalfOf].riskPremium,
restoredPremiumRay: premiumDebtRayRestored
});

uint256 totalDebtRestored = drawnDebtRestored + premiumDebtRayRestored.fromRayUp();
if (!skim) {
IERC20(reserve.underlying).safeTransferFrom(
msg.sender,
address(reserve.hub),
totalDebtRestored
);
}
reserve.hub.restore(reserve.assetId, drawnDebtRestored, premiumDelta);

userPosition.applyPremiumDelta(premiumDelta);
userPosition.drawnShares -= restoredShares.toUint120();
if (userPosition.drawnShares == 0) {
PositionStatus storage positionStatus = _positionStatus[onBehalfOf];
positionStatus.setBorrowing(reserveId, false);
}

emit Repay(reserveId, msg.sender, onBehalfOf, restoredShares, totalDebtRestored, premiumDelta);

return (restoredShares, totalDebtRestored);
}

function _getReserve(uint256 reserveId) internal view returns (Reserve storage) {
Reserve storage reserve = _reserves[reserveId];
require(address(reserve.hub) != address(0), ReserveNotListed());
Expand Down Expand Up @@ -972,4 +1012,8 @@ abstract contract Spoke is ISpoke, Multicall, NoncesKeyed, AccessManagedUpgradea
fnOut := fnIn
}
}

function _onlyPositionManager(address onBehalfOf, address caller) private {
require(_isPositionManager({user: onBehalfOf, manager: caller}), Unauthorized());
}
}
Loading
Loading