Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ark Minimun_gasFee Fix #251

Merged
merged 7 commits into from
Oct 4, 2024
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
101 changes: 83 additions & 18 deletions apps/blockchain/ethereum/src/Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ error BridgeNotEnabledError();
error TooManyTokensError();
error InvalidL1AddressError();
error InvalidL2AddressError();
error MinimumGasFeeError();

uint256 constant MAX_PAYLOAD_LENGTH = 300;

Expand All @@ -42,15 +43,23 @@ contract Starklane is
address[] _collections;
bool _enabled;
bool _whiteListEnabled;
// updatable the minimum gas fee
// Using an arbitrary gas value here for L1-L2 messaging fees, adjustable as network conditions evolve.
// This value serves as a flexible baseline, allowing for real-time adjustments to reflect gas changes.
uint256 _minimumGasFee = 5e13;// 0.00005 ETH

/**
* @notice Initializes the implementation, only callable once.
*
* @param data Data to init the implementation.
*/
function initialize(bytes calldata data) public onlyInit {
(address owner, IStarknetMessaging starknetCoreAddress, uint256 starklaneL2Address, uint256 starklaneL2Selector)
= abi.decode(data, (address, IStarknetMessaging, uint256, uint256));
(
address owner,
IStarknetMessaging starknetCoreAddress,
uint256 starklaneL2Address,
uint256 starklaneL2Selector
) = abi.decode(data, (address, IStarknetMessaging, uint256, uint256));
_enabled = false;
_starknetCoreAddress = starknetCoreAddress;

Expand All @@ -77,6 +86,9 @@ contract Starklane is
uint256[] calldata ids,
bool useAutoBurn
) external payable {
if (msg.value < _minimumGasFee) {
revert MinimumGasFeeError();
}
if (!Cairo.isFelt252(snaddress.unwrap(ownerL2))) {
revert CairoWrapError();
}
Expand Down Expand Up @@ -110,7 +122,8 @@ contract Starklane is
req.ownerL2 = ownerL2;

if (ctype == CollectionType.ERC721) {
(req.name, req.symbol, req.uri, req.tokenURIs) = TokenUtil.erc721Metadata(collectionL1, ids);
(req.name, req.symbol, req.uri, req.tokenURIs) = TokenUtil
.erc721Metadata(collectionL1, ids);
} else {
(req.uri) = TokenUtil.erc1155Metadata(collectionL1);
}
Expand All @@ -123,8 +136,12 @@ contract Starklane is
if (payload.length >= MAX_PAYLOAD_LENGTH) {
revert TooManyTokensError();
}
IStarknetMessaging(_starknetCoreAddress).sendMessageToL2{value: msg.value}(
snaddress.unwrap(_starklaneL2Address), felt252.unwrap(_starklaneL2Selector), payload
IStarknetMessaging(_starknetCoreAddress).sendMessageToL2{
value: msg.value
}(
snaddress.unwrap(_starklaneL2Address),
felt252.unwrap(_starklaneL2Selector),
payload
);

emit DepositRequestInitiated(req.hash, block.timestamp, payload);
Expand All @@ -133,11 +150,13 @@ contract Starklane is
/**
* @notice Withdraw tokens received from L2.
*
* @param request Serialized request containing the tokens to be withdrawed.
* @param request Serialized request containing the tokens to be withdrawed.
*
* @return Address of the collection targetted by the request (or newly deployed).
*/
function withdrawTokens(uint256[] calldata request) external payable returns (address) {
function withdrawTokens(
uint256[] calldata request
) external payable returns (address) {
if (!_enabled) {
revert BridgeNotEnabledError();
}
Expand All @@ -152,18 +171,30 @@ contract Starklane is
// _consumeMessageAutoWithdraw(_starklaneL2Address, request);
revert NotSupportedYetError();
} else {
_consumeMessageStarknet(_starknetCoreAddress, _starklaneL2Address, request);
_consumeMessageStarknet(
_starknetCoreAddress,
_starklaneL2Address,
request
);
}

Request memory req = Protocol.requestDeserialize(request, 0);

address collectionL1 = _verifyRequestAddresses(req.collectionL1, req.collectionL2);
address collectionL1 = _verifyRequestAddresses(
req.collectionL1,
req.collectionL2
);

CollectionType ctype = Protocol.collectionTypeFromHeader(header);

if (collectionL1 == address(0x0)) {
if (ctype == CollectionType.ERC721) {
collectionL1 = _deployERC721Bridgeable(req.name, req.symbol, req.collectionL2, req.hash);
collectionL1 = _deployERC721Bridgeable(
req.name,
req.symbol,
req.collectionL2,
req.hash
);
// update whitelist if needed
_whiteListCollection(collectionL1, true);
} else {
Expand All @@ -174,7 +205,12 @@ contract Starklane is
for (uint256 i = 0; i < req.tokenIds.length; i++) {
uint256 id = req.tokenIds[i];

bool wasEscrowed = _withdrawFromEscrow(ctype, collectionL1, req.ownerL1, id);
bool wasEscrowed = _withdrawFromEscrow(
ctype,
collectionL1,
req.ownerL1,
id
);

if (!wasEscrowed) {
// TODO: perhaps, implement the same interface for ERC721 and ERC1155
Expand All @@ -196,10 +232,16 @@ contract Starklane is
* @param payload Request to cancel
* @param nonce Nonce used for request sending.
*/
function startRequestCancellation(uint256[] memory payload, uint256 nonce) external onlyOwner {
function startRequestCancellation(
uint256[] memory payload,
uint256 nonce
) external onlyOwner {
IStarknetMessaging(_starknetCoreAddress).startL1ToL2MessageCancellation(
snaddress.unwrap(_starklaneL2Address), felt252.unwrap(_starklaneL2Selector), payload, nonce
);
snaddress.unwrap(_starklaneL2Address),
felt252.unwrap(_starklaneL2Selector),
payload,
nonce
);
Request memory req = Protocol.requestDeserialize(payload, 0);
emit CancelRequestStarted(req.hash, block.timestamp);
}
Expand All @@ -212,7 +254,10 @@ contract Starklane is
*/
function cancelRequest(uint256[] memory payload, uint256 nonce) external {
IStarknetMessaging(_starknetCoreAddress).cancelL1ToL2Message(
snaddress.unwrap(_starklaneL2Address), felt252.unwrap(_starklaneL2Selector), payload, nonce
snaddress.unwrap(_starklaneL2Address),
felt252.unwrap(_starklaneL2Selector),
payload,
nonce
);
Request memory req = Protocol.requestDeserialize(payload, 0);
_cancelRequest(req);
Expand Down Expand Up @@ -274,7 +319,11 @@ contract Starklane is
*
* @return array of white listed collections
*/
function getWhiteListedCollections() external view returns (address[] memory) {
function getWhiteListedCollections()
external
view
returns (address[] memory)
{
uint256 offset = 0;
uint256 nbElem = _collections.length;
// solidity doesn't support dynamic length array in memory
Expand Down Expand Up @@ -324,14 +373,30 @@ contract Starklane is
return _enabled;
}

function setL1L2CollectionMapping(address collectionL1, snaddress collectionL2, bool force) external onlyOwner {
function setL1L2CollectionMapping(
address collectionL1,
snaddress collectionL2,
bool force
) external onlyOwner {
if (collectionL1 == address(0x0)) {
revert InvalidL1AddressError();
}
if (snaddress.unwrap(collectionL2) == 0x0) {
revert InvalidL2AddressError();
}
_setL1L2AddressMapping(collectionL1, collectionL2, force);
emit L1L2CollectionMappingUpdated(collectionL1, snaddress.unwrap(collectionL2));
emit L1L2CollectionMappingUpdated(
collectionL1,
snaddress.unwrap(collectionL2)
);
}

function updateMinimumGasFee(uint256 newMinimumGasFee) external onlyOwner {
_minimumGasFee = newMinimumGasFee;
emit MinimumGasFeeUpdated(newMinimumGasFee);
}

function getMinimumGasFee() external view returns (uint256) {
return _minimumGasFee;
}
}
12 changes: 12 additions & 0 deletions apps/blockchain/ethereum/src/IStarklane.sol
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,16 @@ interface IStarklane {
* @param force Force flag
*/
function setL1L2CollectionMapping(address collectionL1, snaddress collectionL2, bool force) external;

/**
* @param newMinimumGasFee New minimum gas fee
*/
function updateMinimumGasFee(
uint256 newMinimumGasFee
) external;

/**
* @return Minimum gas fee
*/
function getMinimumGasFee() external view returns (uint256);
}
7 changes: 7 additions & 0 deletions apps/blockchain/ethereum/src/IStarklaneEvent.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,11 @@ interface IStarklaneEvent {
* @notice L1 L2 collection mapping updated
*/
event L1L2CollectionMappingUpdated(address indexed colllectionL1, uint256 indexed collectionL2);

/**
@notice Minimum gas fee updated
*/
event MinimumGasFeeUpdated(
uint256 indexed gasFee
);
}
26 changes: 26 additions & 0 deletions apps/blockchain/ethereum/test/Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -540,4 +540,30 @@ contract BridgeTest is Test, IStarklaneEvent {
vm.expectRevert(InvalidL2AddressError.selector);
IStarklane(bridge).setL1L2CollectionMapping(collectionL1, invalidCollectionL2, false);
}

//Here is the test for minimum gas validation
function testFail_minimumGasFee() public {
IERC721MintRangeFree(erc721C1).mintRangeFree(alice, 0, 10);

uint256[] memory ids = new uint256[](2);
ids[0] = 0;
ids[1] = 9;

uint256 salt = 0x1;
snaddress to = Cairo.snaddressWrap(0x1);

vm.startPrank(alice);
IERC721(erc721C1).setApprovalForAll(address(bridge), true);
vm.expectRevert(MinimumGasFeeError.selector);
IStarklane(bridge).depositTokens{value: 1000}(salt, address(erc721C1), to, ids, false);
vm.stopPrank();
}

function test_updateMinimumGasFee() public {
IStarklane(bridge).updateMinimumGasFee(0.0001 ether);
assertEq(IStarklane(bridge).getMinimumGasFee(), 0.0001 ether);

IStarklane(bridge).updateMinimumGasFee(0.00001 ether);
assertEq(IStarklane(bridge).getMinimumGasFee(), 0.00001 ether);
}
}
Loading