Skip to content

Instantly share code, notes, and snippets.

@SvenMeyer
Created September 20, 2023 12:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SvenMeyer/736c94a8fb8644e23b16fa165903eb0d to your computer and use it in GitHub Desktop.
Save SvenMeyer/736c94a8fb8644e23b16fa165903eb0d to your computer and use it in GitHub Desktop.
Polkastarter x-chain token sale based on Omni Network
/**
* function for token swap - will be called from LocalETHDeposit conract on Arbitrum or Optimism
* @param _userAccount who deposited ETH on Arbitrum or Optimism
* @param _value amount of ETH deposited by user
*/
function swapXchain(address _userAccount, uint256 _value) external whenNotPaused {
require(isETHTrade(), "token sale not set to ETHTrade");
require(omni.isTxFromOneOf("arbitrum-goerli", "optimism-goerli"));
if (omni.isTxFrom("arbitrum-goerli")) {
require(msg.sender == localETHDepositArbitrum, "wrong contract on Arbitrum");
}
if (omni.isTxFrom("optimism-goerli")) {
require(msg.sender == localETHDepositOptimism, "wrong contract on Optimism");
}
uint256 amount = getTokenAmountForETH(_value);
// Verify `_accountMaxAmount` with off-chain whitelist signature, ...
// otherwise use onchain whitelist to allocate defauly individualMaximumAmount
uint256 accountMaxAmount = determineAccountMaximunAllocation(msg.sender, 0, new bytes(0));
require(accountMaxAmount > 0, "no allocation");
// send purchased token to user
processAmount(_userAccount, _value, amount, accountMaxAmount);
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
import { Pausable } from "@openzeppelin/contracts/security/Pausable.sol";
import { IOmniPortal } from "@omni-network/contracts/contracts/interfaces/IOmniPortal.sol";
contract LocalETHDeposit is AccessControl, Pausable {
address public global; // address of token sale on omni chain
uint256 public startDate; // token sale start date/time
uint256 public endDate; // token sale end date/time
uint256 public individualMaxDeposit; // default maximum amount per account
mapping(address => uint256) public accountDeposits;
IOmniPortal public omni;
modifier onlyAdmin() {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "caller has not admin role");
_;
}
constructor(IOmniPortal _portal, address _global) {
omni = _portal;
global = _global;
startDate = block.timestamp; // by default start now
endDate = startDate + 30 days;
individualMaxDeposit = 1 ether;
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(DEFAULT_ADMIN_ROLE, 0x89b41a6E5AB74fCB9771A3356986185F67F9214C); // add omni test admin
_setupRole(DEFAULT_ADMIN_ROLE, 0xB43b31ae1e148219c110d6ec5925a81b23D5a3bC); // add omni test admin
}
function localETHDeposit() external payable whenNotPaused {
require(block.timestamp >= startDate, "token sale not yet started");
require(block.timestamp <= endDate, "token sale ended");
uint256 value;
address userAccount;
value = msg.value;
userAccount = msg.sender;
uint256 newTotalDeposit = accountDeposits[userAccount] + value;
require(newTotalDeposit <= individualMaxDeposit, "individualMaxDeposit exceeded");
omni.sendOmniTx(global, abi.encodeWithSignature("swapXchain(address,uint256)", userAccount, value));
accountDeposits[userAccount] = newTotalDeposit;
}
/**
* admin functions
*/
function setGlobal(address _tokenSaleContractOmni) public onlyAdmin {
global = _tokenSaleContractOmni;
}
function setStartDate(uint256 _startDate) public onlyAdmin {
startDate = _startDate;
}
function setIndividualMaxDeposit(uint256 _individualMaxDeposit) public onlyAdmin {
individualMaxDeposit = _individualMaxDeposit;
}
function setEndDate(uint256 _endDate) public onlyAdmin {
endDate = _endDate;
}
/**
* @dev called by the owner to pause, triggers stopped state
*/
function pause() external onlyAdmin {
_pause();
}
/**
* @dev called by the owner to unpause, returns to normal state
*/
function unpause() external onlyAdmin {
_unpause();
}
function safePullETH() external onlyAdmin {
payable(msg.sender).transfer(address(this).balance);
}
}
@SvenMeyer
Copy link
Author

SvenMeyer commented Sep 21, 2023

Just saw that line 21 of FixedSwap.sol has a bug.
msg.sender is the Omni contract, but we want the maximun allocation for the user, so thus it should be

uint256 accountMaxAmount = determineAccountMaximunAllocation(_userAccount, 0, new bytes(0));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment