Skip to content
Draft
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
23 changes: 21 additions & 2 deletions src/L1AtomicSwapStakeManager.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";

import "./bridges/IL1Bridge.sol";
import "./common/Errors.sol";
Expand All @@ -17,6 +20,9 @@ import "./types/StakeManagerStructs.sol";
import "./types/XlpInsolvencyPool.sol";

contract L1AtomicSwapStakeManager is IL1AtomicSwapStakeManager, Ownable {
using MessageHashUtils for bytes;
using ECDSA for bytes32;

struct Config {
uint256 claimDelay;
uint256 destBeforeOriginMinGap;
Expand Down Expand Up @@ -94,7 +100,8 @@ contract L1AtomicSwapStakeManager is IL1AtomicSwapStakeManager, Ownable {
}

/// @inheritdoc IL1AtomicSwapStakeManager
function addChainsInfo(uint256[] calldata chainIds, ChainInfo[] calldata chainsInfo) public payable {
function addChainsInfo(uint256[] calldata chainIds, ChainInfo[] calldata chainsInfo, bytes calldata ownerSignature) public payable {
_verifyOwnerSignature(chainIds, chainsInfo, ownerSignature);
require(
chainIds.length == chainsInfo.length,
InvalidLength("chainIds/chainsInfo", chainIds.length, chainsInfo.length)
Expand All @@ -113,6 +120,18 @@ contract L1AtomicSwapStakeManager is IL1AtomicSwapStakeManager, Ownable {
emit StakeLocked(msg.sender, chainIds, msg.value);
}

function _verifyOwnerSignature(uint256[] calldata chainIds, ChainInfo[] calldata chainsInfo, bytes calldata ownerSignature) internal {
address _owner = owner();
if (_owner == address(0)){
return;
}
bytes memory rawMessage = abi.encode(chainIds, chainsInfo);
bytes32 messageHash = rawMessage.toEthSignedMessageHash();
(address recovered, ECDSA.RecoverError err, bytes32 errArg) = messageHash.tryRecoverCalldata(ownerSignature);
require(err == ECDSA.RecoverError.NoError, "Owner signature recovery error!");
require(recovered == _owner, "Invalid owner address signature!");
}

/// @inheritdoc IL1AtomicSwapStakeManager
function getStakeInfo(
address xlp,
Expand Down Expand Up @@ -336,7 +355,7 @@ contract L1AtomicSwapStakeManager is IL1AtomicSwapStakeManager, Ownable {
uint256 destinationChainId,
DisputeType disputeType,
SlashShareRole role
) external {
) external onlyOwner {
if (disputeType == DisputeType.INSOLVENT_XLP) {
_claimInsolvencyShare(l1XlpAddress, originationChainId, destinationChainId, role);
return;
Expand Down
19 changes: 14 additions & 5 deletions src/destination/DestinationSwapDisputeManager.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import "@openzeppelin/contracts/access/Ownable.sol";

import "./DestinationSwapBase.sol";
import "../common/utils/AtomicSwapUtils.sol";
import "../interfaces/IL1AtomicSwapStakeManager.sol";
Expand All @@ -15,23 +17,30 @@ import "../AtomicSwapStorage.sol";
import "../common/utils/BridgeMessengerLib.sol";
import "../common/utils/ChunkReportLib.sol";

contract DestinationSwapDisputeManager is DestinationSwapBase, IL2XlpPenalizer {
contract DestinationSwapDisputeManager is DestinationSwapBase, IL2XlpPenalizer, Ownable {
using AtomicSwapUtils for AtomicSwapVoucher;
using EnumerableMap for EnumerableMap.AddressToAddressMap;

function _disputeKey(address l2XlpAddressToSlash, uint256 origChainId, uint256 destChainId, DisputeType disputeType) internal pure returns (bytes32) {
return keccak256(abi.encode(l2XlpAddressToSlash, origChainId, destChainId, disputeType));
}

constructor (address _l2Connector, address _l1Connector, address _entryPoint, uint256 l1SlashGasLimit)
constructor (
address _l2Connector,
address _l1Connector,
address _entryPoint,
uint256 l1SlashGasLimit,
address owner
)
DestinationSwapBase(_entryPoint, l1SlashGasLimit)
Ownable(owner)
{
l2Connector = IL2Bridge(_l2Connector);
l1Connector = _l1Connector;
}

/// @inheritdoc IL2XlpPenalizer
function accuseFalseVoucherOverride(AtomicSwapVoucherRequest[] calldata voucherRequests, AtomicSwapVoucher[] calldata voucherOverrides, address payable l1Beneficiary) public override {
function accuseFalseVoucherOverride(AtomicSwapVoucherRequest[] calldata voucherRequests, AtomicSwapVoucher[] calldata voucherOverrides, address payable l1Beneficiary) public override onlyOwner {
require(
voucherRequests.length == voucherOverrides.length && voucherRequests.length > 0,
InvalidLength("requests/overrides", voucherRequests.length, voucherOverrides.length)
Expand Down Expand Up @@ -87,7 +96,7 @@ contract DestinationSwapDisputeManager is DestinationSwapBase, IL2XlpPenalizer {
}

/// @inheritdoc IL2XlpPenalizer
function proveVoucherSpent(AtomicSwapVoucherRequest[] calldata voucherRequests, AtomicSwapVoucher[] calldata vouchers, address payable l1Beneficiary, address l2XlpAddressToSlash) public override {
function proveVoucherSpent(AtomicSwapVoucherRequest[] calldata voucherRequests, AtomicSwapVoucher[] calldata vouchers, address payable l1Beneficiary, address l2XlpAddressToSlash) public override onlyOwner {
require(
voucherRequests.length == vouchers.length && voucherRequests.length > 0,
InvalidLength("requests/vouchers", voucherRequests.length, vouchers.length)
Expand Down Expand Up @@ -145,7 +154,7 @@ contract DestinationSwapDisputeManager is DestinationSwapBase, IL2XlpPenalizer {
uint256 nonce,
bytes32 committedRequestIdsHash,
uint256 committedVoucherCount
) public override {
) public override onlyOwner {
require(voucherRequests.length == vouchers.length && voucherRequests.length > 0, InvalidLength("requests/vouchers", voucherRequests.length, vouchers.length));

address l2XlpAddressToSlash = vouchers[0].originationXlpAddress;
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/IL1AtomicSwapStakeManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ interface IL1AtomicSwapStakeManager {
/// @notice Adds chain information for supported chains.
/// @param chainIds Array of chain IDs to add.
/// @param chainsInfo Array of chain information corresponding to each chain ID.
function addChainsInfo(uint256[] calldata chainIds, ChainInfo[] calldata chainsInfo) external payable;
/// @param ownerSignature Signature of the L1 admin account if it is set to a non-zero address.
function addChainsInfo(uint256[] calldata chainIds, ChainInfo[] calldata chainsInfo, bytes calldata ownerSignature) external payable;

/// @notice Retrieves stake information for a xlp.
/// @param xlp The xlp's address.
Expand Down
17 changes: 10 additions & 7 deletions src/origin/OriginationSwapDisputeManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.28;

import "@account-abstraction/contracts/core/Helpers.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "../AtomicSwapStorage.sol";
Expand All @@ -19,7 +20,7 @@ import "../types/ReportLegs.sol";
import "../types/SlashOutput.sol";
import "./OriginSwapBase.sol";

contract OriginationSwapDisputeManager is OriginSwapBase, IL2XlpDisputeManager {
contract OriginationSwapDisputeManager is OriginSwapBase, IL2XlpDisputeManager, Ownable {
using AssetUtils for Asset;
using AtomicSwapUtils for AtomicSwapVoucher;
using AtomicSwapUtils for AtomicSwapVoucherRequest;
Expand All @@ -34,7 +35,8 @@ contract OriginationSwapDisputeManager is OriginSwapBase, IL2XlpDisputeManager {
uint256 _voucherMinExpirationTime,
uint256 _disputeBondPercent,
uint256 _flatNativeBond,
uint256 l1DisputeGasLimit
uint256 l1DisputeGasLimit,
address owner
)
OriginSwapBase(
_voucherUnlockDelay,
Expand All @@ -45,6 +47,7 @@ contract OriginationSwapDisputeManager is OriginSwapBase, IL2XlpDisputeManager {
_flatNativeBond,
l1DisputeGasLimit
)
Ownable(owner)
{
l2Connector = IL2Bridge(_l2Connector);
l1Connector = _l1Connector;
Expand Down Expand Up @@ -83,7 +86,7 @@ contract OriginationSwapDisputeManager is OriginSwapBase, IL2XlpDisputeManager {
uint256 nonce,
bytes32 committedRequestIdsHash,
uint256 committedVoucherCount
) external payable override {
) external payable override onlyOwner {
bytes32 reportId = _processInsolvencyDisputeChunk(
disputeVouchers,
l2XlpAddressToSlash,
Expand All @@ -107,12 +110,12 @@ contract OriginationSwapDisputeManager is OriginSwapBase, IL2XlpDisputeManager {
}

/// @inheritdoc IL2XlpDisputeManager
function disputeVoucherOverride(DisputeVoucher[] calldata disputeVouchers, address l2XlpAddressToSlash, address payable l1Beneficiary) external payable override {
function disputeVoucherOverride(DisputeVoucher[] calldata disputeVouchers, address l2XlpAddressToSlash, address payable l1Beneficiary) external payable override onlyOwner {
_initiateDisputeWithBond(disputeVouchers, l2XlpAddressToSlash, l1Beneficiary, DisputeType.VOUCHER_OVERRIDE);
}

/// @inheritdoc IL2XlpDisputeManager
function disputeXlpUnspentVoucherClaim(DisputeVoucher[] calldata disputeVouchers, address payable l1Beneficiary) external payable override {
function disputeXlpUnspentVoucherClaim(DisputeVoucher[] calldata disputeVouchers, address payable l1Beneficiary) external payable override onlyOwner {
require(disputeVouchers.length > 0, InvalidLength("No disputed vouchers", 0, disputeVouchers.length));
bytes32 firstId = disputeVouchers[0].voucherRequest.getVoucherRequestId();
AtomicSwapMetadata storage firstMetadata = outgoingAtomicSwaps[firstId];
Expand Down Expand Up @@ -361,7 +364,7 @@ contract OriginationSwapDisputeManager is OriginSwapBase, IL2XlpDisputeManager {
}

/// @inheritdoc IL2XlpDisputeManager
function reportJustifiedDisputeRequests(bytes32 reportId, bytes32[] calldata requestIds) external override {
function reportJustifiedDisputeRequests(bytes32 reportId, bytes32[] calldata requestIds) external override onlyOwner {
require(requestIds.length > 0, InvalidLength("No penalized vouchers", 0, requestIds.length));
bytes32 requestIdsHash = _requestIdsHashByReportId[reportId];
require(requestIdsHash != bytes32(0), InvalidReportId(bytes32(0), reportId));
Expand Down Expand Up @@ -592,7 +595,7 @@ contract OriginationSwapDisputeManager is OriginSwapBase, IL2XlpDisputeManager {

/// @notice After L1 slashing, a disputer can withdraw both the dispute bond and the override bond for vouchers it currently owns.
/// @dev This implements: justified dispute → both bonds go to the disputer.
function withdrawDisputeBonds(bytes32[] calldata requestIds) external override {
function withdrawDisputeBonds(bytes32[] calldata requestIds) external override onlyOwner {
for (uint256 i = 0; i < requestIds.length; i++) {
AtomicSwapMetadata storage metadata = outgoingAtomicSwaps[requestIds[i]];
require(metadata.core.status == AtomicSwapStatus.PENALIZED, InvalidSwapStatus(requestIds[i], metadata.core.status, AtomicSwapStatus.PENALIZED));
Expand Down