Skip to main content

Documentation


SigmaSwap is a platform that bridges the LUKSO and the Ethereum networks. This bridge enables users to seamlessly transfer value between these two blockchain environments. It primarily facilitates the conversion of LYX tokens from the LUKSO network to wLYX (wrapped LYX) tokens on the Ethereum network, and vice versa.

You can swap your wLYX tokens for any token you want on the Ethereum blockchain and even buy wLYX with LYXe, ETH or any other token you want to bridge them back to LYX.

You can trade wLYX on the Ethereum blockchain by using the custom wLYX token contract address 0x0808E6C4400BdE1d70Db0d02170b67DE05E07eF5, which you can also find on Etherscan here.

And if you want to swap on Uniswap now, these links will take you directly to the ETH/wLYX Swap or the LYXe/wLYX Swap

The General Process of Bridging:


  1. Funds Transfer and Backend Monitoring: A user transfers funds from their Universal Profile or External Owned Account (EOA) to a gateway EOA or UP. The backend system monitors every new block for transactions.
  2. Fee Deduction and Transaction Validation: The smart-contract calculates the transaction fee by deducting a small, configurable amount of LYX (based on its current price) to cover server costs. If the remaining LYX is insufficient (less than zero after fee deduction), the transaction fee is reverted.
  3. Transaction Recording and Status Checking: Once the transaction is validated, the backend records it in a database. The user can then check the transaction status via a backend endpoint. If a configurable number of blocks (e.g., 64) have passed, then the backend records it the minting comes available. The backend also checks the Ethereum network for the usage of this signature and updates the status accordingly.
  4. Minting Process on the Ethereum network: The user initiates a minting process on the Ethereum network with the data provided by the backend. The Wrapped LYX smart contract verifies if the recovered signature matches the owner and if the nonce (emitted by bridge contract) has not been used before.
  5. Minting Completion and Event Emission: Upon successful verification, the Wrapped LYX smart contract completes the minting process and emits an event, which is then captured by the backend, marking the transaction as completed.

Bridge

Steps Explained


info

Before you start, make sure you have some Ethereum to pay for gas fees on the Ethereum network and LYX on your Universal Profile.

The SigmaSwap Bridge enables transferring value between the LUKSO network and the Ethereum network by wrapping LYX tokens to wLYX (wrapped LYX) and vice versa.

LYX to wLYX (Wrapped LYX)

info

Keep track of the threshold, if the threshold balance is low the DAO needs to approve new funds.


  1. Connection: User connects Universal Profile and MetaMask.
  2. Bridge Direction Selection: User decides in which direction he wants to wrap or unwrap his tokens.
  3. Sending tokens: User sends deposit transaction (paying in LYX) using their Universal Profiles with their MetaMask EOA supplied as parameter.
  4. Transaction validation: User waits some blocks (configurable) for backend to pick up the transaction.
  5. Sign challenge: User gets challenge from backend and signs it with metamask
  6. Mint wLYX: User gets signed parameters from the backend to mint wLYX tokens on the Ethereum network.
  7. Receive tokens: User mints his token on the Ethereum network and receives his wLYX, while the original LYX is locked in the smart contract of the bridge. To withdraw LYX, an equivalent amount of wLYX must be burned.

wLYX (Wrapped LYX) to LYX


  1. Connection: Users connect their Universal Profile and a wallet that can access the Ethereum network. For example MetaMask.
  2. Token Burning:: Users initiate the burning process by calling the burn function on the wLYX contract. This action triggers an event that includes the Recipient address.
  3. Transfer Back to User:: The backend system identifies this event and proceeds to transfer LYX tokens on the LUKSO Mainnet back to the user.

Trade wLYX


By using wLYX everyone that has acces to Uniswap can buy LYX on a DEX via wLYX. You can buy LYX from everywhere via wLYX or just trade your wLYX tokens on Uniswap.

wlyx/lyxe

Provide Liquidity


To enable people from everywhere to buy LYX, we also need to provide enough wLYX. You can join our liquidity pool and start making money by providing liquidity in wLYX on Uniswap.

You can read how to provide liquidity in ETH/wLYX on Uniswap here and in LYXe/wLYX here.


Backend


  • Wrapped LYX Smart Contract Validation: Before completing the minting process, the Wrapped LYX smart contract validates the following:

    -If there is enough threshold balance approved by the DAO to swap.

    -Ensures that the EC-recovered signature matches the owner.

    -Checks a mapping structure to verify whether the nonce has not already been used.

  • Event Emission: The Wrapped LYX smart contract commits the minting operation and generates the relevant event, which is subsequently detected by the backend.

  • The signature generated for this process follows this format: sign(keccak256(value, recepient, bridgeNonce, chainID, _contractAddress)).

Bridge

Security


Semi-Automatic Mechanism Managed by our DAO Our bridge incorporates a semi-automatic mechanism as an additional security layer. This mechanism is overseen by our DAO, which manages the bridge's backend. The DAO comprises members from the Sigmatic and M8B teams. Each DAO member has the authority to raise the swap threshold by 1000 tokens. The current threshold balance can be viewed in the swapper UI. We are committed to regularly sign authorization new tokens for the threshold. For substantial token swaps, please contact us on Discord. Any modifications to our backend require a DAO vote, with a consensus needed for implementation. Although we have the capability to add or remove DAO members, such actions are contingent upon a prior DAO vote and consensus.

Securing Private Keys with HashiCorp Vault: We prioritize the security of our private keys by leveraging the robust capabilities of HashiCorp Vault. This advanced tool ensures that sensitive data, such as private keys, are securely managed and protected. HashiCorp Vault provides a fortified environment for our keys, with strict access controls and advanced encryption, significantly reducing the risk of unauthorized access and data breaches.

Audits: Our code has been audited by M8B you can see the audit reports here.

Automated Tests and Code Coverage: Our commitment to software reliability is underscored by an extensive testing regime, reflected in a remarkable 97.96% code coverage. This high coverage percentage demonstrates our thorough approach to testing, ensuring that nearly every aspect of our codebase has been rigorously tested for maximum security and performance. You can check our code coverage report here.

Review by Experts: We allowed other experts to have a look at our code and review it for us. We are confident that with all the security measures we took that our code is solid and secure.

A Note on Responsibility


While we strive for excellence, interacting with any smart contract comes with inherent risks. We remind our users that engaging with our smart contracts is at their own risk. Despite our thorough processes, the possibility of unforeseen issues always exists in the ever-evolving digital landscape.

Code


All of our smart-contracts are open-sourced, they are all verified and public at the LUKSO and Ethereum Blockchain.

In the section below we also explained some of our code and flow.

Pseudocode

const ownWalletAddr = 0x...
const ownWalletPrivk = 0x...
fn findTransactions(rpc, db) {
blockN = db.getLastBlock() + 1
block = rpc.ethGetBlockByNumber(blockN, true)
output = []
foreach block.transactions as transaction {
if transaction.to == ownWalletAddr {
output.push({
from: transaction.sender
value: transaction.value
tx: transaction.hash
block: blockN
done: false
})
}
}
db.begin()
db.setLastBlock(blockN)
foreach output as record {
db.createTx(record)
}
db.commit()
}
// simple getter
fn getTransactions()
fn getStatus(request, response, db, rpc) {
txn = db.findTxByHash(request.hash)
if txn == null {
response.send(404)
return
}
if txn.done {
response.send({
status: finished
})
return
}
if rpc.currentBlockNumber() > txn.blockN + 64 {
response.send({
status: readyForMint
data: ecdsaSign(keccak256(tx.from, tx.value, tx.id), ownWalletPrivk)
})
} else {
response.send({
status: waiting
})
}
}

Contact


If you have any questions or need some support, please reach out to us on Discord or Common Ground.

Report Issues


If you have any issues using our website or swapper, please report them as detailed as possible here. You can also send us an email.