Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
35 changes: 18 additions & 17 deletions contracts/Hyperdrive.sol
Original file line number Diff line number Diff line change
Expand Up @@ -399,31 +399,32 @@ contract Hyperdrive is MultiToken {
}

/// @notice Closes a short position with a specified maturity time.
/// @param _assetId The asset ID of the short.
/// @param _openSharePrice The opening share price of the short.
/// @param _maturityTime The maturity time of the short.
/// @param _bondAmount The amount of shorts to close.
function closeShort(uint256 _assetId, uint256 _bondAmount) external {
function closeShort(
uint256 _openSharePrice,
uint32 _maturityTime,
uint256 _bondAmount
) external {
if (_bondAmount == 0) {
revert Errors.ZeroAmount();
}

// Ensure that the asset ID refers to a short and get the open share
// price and maturity time from the short key.
(
AssetId.AssetIdPrefix prefix,
uint256 openSharePrice,
uint256 maturityTime
) = AssetId.decodeAssetId(_assetId);
if (prefix != AssetId.AssetIdPrefix.Short) {
revert Errors.UnexpectedAssetId();
}

// Burn the shorts that are being closed.
_burn(_assetId, msg.sender, _bondAmount);
uint256 assetId = AssetId.encodeAssetId(
AssetId.AssetIdPrefix.Short,
_openSharePrice,
_maturityTime
);
_burn(assetId, msg.sender, _bondAmount);
shortsOutstanding -= _bondAmount;

// Calculate the pool and user deltas using the trading function.
uint256 timeRemaining = block.timestamp < maturityTime
? (maturityTime - block.timestamp).divDown(positionDuration) // use divDown to scale to fixed point
uint256 timeRemaining = block.timestamp < uint256(_maturityTime)
? (uint256(_maturityTime) - block.timestamp).divDown(
positionDuration
) // use divDown to scale to fixed point
: 0;
(
uint256 poolShareDelta,
Expand Down Expand Up @@ -453,7 +454,7 @@ contract Hyperdrive is MultiToken {
sharePrice.mulDown(sharePayment)
);
uint256 interestProceeds = sharePrice
.divDown(openSharePrice)
.divDown(_openSharePrice)
.sub(FixedPointMath.ONE_18)
.mulDown(_bondAmount);
bool success = baseToken.transfer(
Expand Down
38 changes: 0 additions & 38 deletions contracts/libraries/AssetId.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,42 +51,4 @@ library AssetId {
}
return id;
}

/// @dev Decodes an asset ID into an identifier, extra data, and a timestamp.
/// @param _id The asset ID.
/// TODO: Update this comment when we make the range more restrictive.
/// @return prefix A one byte prefix that specifies the asset type.
/// @return data Data associated with the asset. This is an efficient way of
/// fingerprinting data as the user can supply this data, and the
/// token balance ensures that the data is associated with the asset.
/// @return timestamp_ A timestamp associated with the asset.
function decodeAssetId(
uint256 _id
)
internal
pure
returns (AssetIdPrefix prefix, uint256 data, uint256 timestamp_)
{
// [identifier: 8 bits][data: 216 bits][timestamp: 32 bits]
assembly {
prefix := shr(0xf8, _id)
data := and(
shr(0x20, _id),
0xffffffffffffffffffffffffffffffffffffffffffffffffffffff
)
timestamp_ := and(shr(0x20, _id), 0xffffffff)
}
// In the case of shorts, extra data is the share price at which the
// short was opened. Hyperdrive assumes that the yield source accrues
// non-negative interest, so an opening share price less than the fixed
// point multiplicative identity indicates corruption. In the case of
// longs, the extra data is unused.
if (
(prefix == AssetIdPrefix.Long && data > 0) ||
(prefix == AssetIdPrefix.Short && data < FixedPointMath.ONE_18)
) {
revert Errors.AssetIDCorruption();
}
return (prefix, data, timestamp_);
}
}