Skip to content

Commit

Permalink
update gas proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
Skyewwww committed Nov 14, 2024
1 parent 1007ab5 commit 31c7e37
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 9 deletions.
82 changes: 74 additions & 8 deletions contracts/SmartRoute/DODOGasProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ contract DODOGasProxy is InitializableOwnable {
// DODOApproveProxy address for token claiming
address public immutable _DODO_APPROVE_PROXY_;
uint256 public nonce;
uint256 public totalGasFee; // Total transferred in gas fee collected
uint256 public totalBridgeGasFee; // Total bridge gas fee collected

// Gas fee mapping for each target chain
mapping(uint64 => uint256) public chainGasFee;
// Gas fee mapping for each cross-chain bridge
mapping(uint64 => uint256) public bridgeGasFee;
// Whitelist mapping for approved contracts
mapping(address => bool) public isWhiteListedContract;
// Whitelist mapping for approved approve contracts
Expand All @@ -34,15 +38,32 @@ contract DODOGasProxy is InitializableOwnable {

// Pause state
bool public paused;

// For readability
struct ChainGasFee {
uint64 chainId;
uint256 gasFee;
}

struct BridgeGasFee {
uint64 chainId;
uint256 gasFee;
}

uint64[] internal chainIndexs;
uint64[] internal bridgeIndexs;

// ============ Events ============

event GasFeeChanged(uint64 chainId, uint256 newFee);
event BridgeGasFeeChanged(uint64 chainId, uint256 newFee);
event WhiteListChanged(address indexed target, bool isWhiteListed);
event WhiteListApproveChanged(address indexed target, bool isWhiteListed);
event BotChanged(address indexed newBot);
event GasFeePaid(address payer, uint64 chainId, uint256 gasFee, bytes32 externalID);
event BridgeGasFeePaid(address payer, uint64 chainId, uint256 gasFee, bytes32 externalID);
event PausedStateChanged(bool newState);
event NativeDrip(address payer, uint64 chainId, uint256 amount, bytes32 externalID);

// ============ Modifiers ============

Expand Down Expand Up @@ -99,10 +120,27 @@ contract DODOGasProxy is InitializableOwnable {

for (uint256 i = 0; i < chainIds.length; i++) {
chainGasFee[chainIds[i]] = gasFees[i];
bridgeIndexs.push(chainIds[i]);
emit GasFeeChanged(chainIds[i], gasFees[i]);
}
}

/// @notice Batch set gas fees for cross-chain bridges
/// @param chainIds Array of chain IDs
/// @param gasFees Array of corresponding gas fees
function batchSetBridgeGasFee(
uint64[] calldata chainIds,
uint256[] calldata gasFees
) external onlyBot {
require(chainIds.length == gasFees.length, "DODOGasProxy: LENGTH_MISMATCH");

for (uint256 i = 0; i < chainIds.length; i++) {
bridgeGasFee[chainIds[i]] = gasFees[i];
bridgeIndexs.push(chainIds[i]);
emit BridgeGasFeeChanged(chainIds[i], gasFees[i]);
}
}

/// @notice Batch set contract whitelist status
/// @param targets Array of target addresses
/// @param isWhiteListed Array of whitelist status
Expand Down Expand Up @@ -142,6 +180,8 @@ contract DODOGasProxy is InitializableOwnable {
/// @param approveTarget Address to approve tokens for
/// @param executeTarget Contract to execute call on
/// @param transferInGasFee Extra amount of gas fee transferred in
/// @param transferbridgeGasFee Extra amount of gas fee for bridge transferred in
/// @param nativeDrip Extra amount of native token to drip to target contract
/// @param callData Call data for target contract
function proxyCall(
uint64 chainId,
Expand All @@ -150,22 +190,25 @@ contract DODOGasProxy is InitializableOwnable {
address approveTarget,
address executeTarget,
uint256 transferInGasFee,
uint256 transferbridgeGasFee,
uint256 nativeDrip,
bytes calldata callData
) external payable whenNotPaused returns (bytes memory) {
// Check if target contract is whitelisted
require(isWhiteListedApproveContract[approveTarget], "DODOGasProxy: NOT_WHITELISTED");
require(isWhiteListedContract[executeTarget], "DODOGasProxy: NOT_WHITELISTED");

// Check and collect gas fee
uint256 requiredGasFee = chainGasFee[chainId];
require(requiredGasFee > 0, "DODOGasProxy: GAS_FEE_NOT_SET");
require(transferInGasFee > requiredGasFee, "DODOGasProxy: INSUFFICIENT_TRANSFER_IN_GAS_FEE");
require(chainGasFee[chainId] > 0 && bridgeGasFee[chainId] > 0, "DODOGasProxy: GAS_FEE_NOT_SET");
require(transferInGasFee >= chainGasFee[chainId], "DODOGasProxy: INSUFFICIENT_TRANSFER_IN_GAS_FEE");
require(transferbridgeGasFee >= bridgeGasFee[chainId], "DODOGasProxy: INSUFFICIENT_BRIDGE_GAS_FEE");


// Transfer user tokens
if(fromToken == _ETH_ADDRESS_) {
require(msg.value >= fromTokenAmount + transferInGasFee, "DODOGasProxy: INVALID_ETH_AMOUNT");
require(msg.value >= fromTokenAmount + transferInGasFee + transferbridgeGasFee + nativeDrip, "DODOGasProxy: INVALID_ETH_AMOUNT");
} else {
require(msg.value >= transferInGasFee, "DODOGasProxy: INVALID_GAS_FEE");
require(msg.value >= transferInGasFee + transferbridgeGasFee + nativeDrip, "DODOGasProxy: INVALID_GAS_FEE");
// Use DODOApproveProxy to claim tokens instead of transferFrom
IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(
fromToken,
Expand All @@ -181,18 +224,41 @@ contract DODOGasProxy is InitializableOwnable {

// generate externalID
nonce++;
bytes32 externalID = keccak256(abi.encodePacked(block.timestamp, msg.sender, chainId, transferInGasFee, nonce));
emit GasFeePaid(msg.sender, chainId, requiredGasFee, externalID);
bytes32 externalID = keccak256(abi.encodePacked(block.timestamp, msg.sender, chainId, transferInGasFee, transferbridgeGasFee, nonce));
totalGasFee += transferInGasFee;
totalBridgeGasFee += transferbridgeGasFee;
emit GasFeePaid(msg.sender, chainId, transferInGasFee, externalID);
emit BridgeGasFeePaid(msg.sender, chainId, transferbridgeGasFee, externalID);

// Call target contract
(bool success, bytes memory result) = executeTarget.call{
value: fromToken == _ETH_ADDRESS_ ? fromTokenAmount : 0
value: fromToken == _ETH_ADDRESS_ ? fromTokenAmount + nativeDrip : nativeDrip
}(callData);

if(nativeDrip > 0) {
emit NativeDrip(msg.sender, chainId, nativeDrip, externalID);
}

require(success, "DODOGasProxy: CALL_FAILED");
return result;
}

function getChainGasFee() public view returns (ChainGasFee[] memory) {
ChainGasFee[] memory list = new ChainGasFee[](chainIndexs.length);
for (uint256 i = 0; i < chainIndexs.length; i++) {
list[i] = ChainGasFee(chainIndexs[i], chainGasFee[chainIndexs[i]]);
}
return list;
}

function getBridgeGasFee() public view returns (BridgeGasFee[] memory) {
BridgeGasFee[] memory list = new BridgeGasFee[](bridgeIndexs.length);
for (uint256 i = 0; i < bridgeIndexs.length; i++) {
list[i] = BridgeGasFee(bridgeIndexs[i], bridgeGasFee[bridgeIndexs[i]]);
}
return list;
}

receive() external payable {}
fallback() external payable {}
}
3 changes: 2 additions & 1 deletion contracts/SmartRoute/DOODGasDistributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ contract DOODGasDistributor is InitializableOwnable {
emit Distribution(to, distributionAmount, externalId);
}

function setMaxAmount(uint256 _maxAmount) external onlyOwner {
function setMaxAmount(uint256 _maxAmount) external {
require(msg.sender == bot || msg.sender == _OWNER_, "Only bot or owner");
maxAmount = _maxAmount;
emit MaxAmountUpdated(_maxAmount);
}
Expand Down

0 comments on commit 31c7e37

Please sign in to comment.