Examples
Complete working examples using the Lux Standard Library
Examples
Learn by example with these complete, working implementations.
Token Examples
Create a Bridgeable Token
A token that can be minted/burned by bridge admins for cross-chain transfers:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@luxfi/contracts/tokens/LRC20B.sol";
contract BridgedUSDC is LRC20B {
constructor() LRC20B("Bridged USDC", "USDC.e") {
// Deployer is admin, can grant admin role to bridge
}
function decimals() public pure override returns (uint8) {
return 6; // USDC uses 6 decimals
}
}Create a Capped Token
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@luxfi/contracts/tokens/LRC20/LRC20Capped.sol";
contract CappedToken is LRC20Capped {
constructor()
LRC20Capped("Capped Token", "CAP", 1_000_000 * 10**18)
{
_mint(msg.sender, 100_000 * 10**18); // Initial supply
}
}DeFi Examples
Self-Repaying Loan with Synths
Deposit collateral, mint synthetic tokens, and let yield repay your debt:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@luxfi/contracts/synths/interfaces/IAlchemistV2.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract SynthLoan {
IAlchemistV2 public alchemist;
constructor(address _alchemist) {
alchemist = IAlchemistV2(_alchemist);
}
/// @notice Deposit yield token and mint synths
function depositAndMint(
address yieldToken,
uint256 depositAmount,
uint256 mintAmount,
address recipient
) external {
// Transfer yield token from user
IERC20(yieldToken).transferFrom(msg.sender, address(this), depositAmount);
IERC20(yieldToken).approve(address(alchemist), depositAmount);
// Deposit collateral
alchemist.deposit(yieldToken, depositAmount, msg.sender);
// Mint synths against collateral
alchemist.mint(mintAmount, recipient);
}
/// @notice Check remaining debt (will decrease as yield accrues)
function getDebt(address account) external view returns (int256) {
(int256 debt, ) = alchemist.accounts(account);
return debt;
}
}Perpetual Trading Position
Open a leveraged long position on LUX:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@luxfi/contracts/perps/core/interfaces/IRouter.sol";
import "@luxfi/contracts/perps/core/interfaces/IVault.sol";
contract PerpTrader {
IRouter public router;
IVault public vault;
constructor(address _router, address _vault) {
router = IRouter(_router);
vault = IVault(_vault);
}
/// @notice Open a long position with leverage
function openLong(
address collateralToken,
address indexToken,
uint256 collateralAmount,
uint256 sizeDelta
) external payable {
router.increasePosition{value: msg.value}(
collateralToken,
indexToken,
collateralAmount,
0, // minOut
sizeDelta,
true, // isLong
type(uint256).max // acceptablePrice
);
}
/// @notice Close a position
function closePosition(
address collateralToken,
address indexToken,
uint256 sizeDelta,
bool isLong
) external {
router.decreasePosition(
collateralToken,
indexToken,
0, // collateralDelta
sizeDelta,
isLong,
msg.sender, // receiver
0 // acceptablePrice
);
}
}Governance Examples
Create a DAO
Set up a DAO with token voting:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@luxfi/contracts/governance/Governor.sol";
import "@luxfi/contracts/governance/Timelock.sol";
import "@luxfi/contracts/governance/GoveranceToken.sol";
contract MyDAO is Governor {
constructor(
address _token,
address _timelock
) Governor(
"My DAO",
_token,
_timelock,
1 days, // Voting delay
7 days, // Voting period
100_000e18 // Proposal threshold (100k tokens)
) {}
}
// Deploy sequence:
// 1. Deploy GovernanceToken
// 2. Deploy Timelock(minDelay, proposers, executors, admin)
// 3. Deploy MyDAO(token, timelock)
// 4. Grant proposer/executor roles to DAOBridge Examples
Cross-Chain Token Transfer
Use Warp messaging to teleport tokens:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@luxfi/contracts/bridge/Teleport.sol";
contract TokenTeleporter {
Teleport public teleport;
constructor(address _teleport) {
teleport = Teleport(_teleport);
}
/// @notice Send tokens to another chain
function sendCrossChain(
bytes32 destinationChainId,
address recipient,
address token,
uint256 amount
) external {
// Transfer tokens to this contract first
IERC20(token).transferFrom(msg.sender, address(this), amount);
IERC20(token).approve(address(teleport), amount);
// Initiate cross-chain transfer
teleport.send(destinationChainId, recipient, token, amount);
}
}Multi-Sig Examples
Create a Safe Wallet
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@luxfi/contracts/safe/SafeFactory.sol";
contract DeploySafe {
SafeFactory public factory;
constructor(address _factory) {
factory = SafeFactory(_factory);
}
/// @notice Create a 2-of-3 multisig
function createTeamSafe(
address[] calldata owners
) external returns (address safe) {
require(owners.length == 3, "Need 3 owners");
safe = factory.createSafe(
owners,
2 // threshold
);
}
}Testing Examples
Foundry Test with Forks
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "forge-std/Test.sol";
import "@luxfi/contracts/synths/AlchemistV2.sol";
contract IntegrationTest is Test {
AlchemistV2 alchemist;
function setUp() public {
// Fork Lux mainnet at specific block
vm.createSelectFork("lux_mainnet", 1_000_000);
// Get deployed Alchemist
alchemist = AlchemistV2(0x...);
}
function testDeposit() public {
address user = makeAddr("user");
address yieldToken = 0x...; // yvWETH
deal(yieldToken, user, 10 ether);
vm.startPrank(user);
IERC20(yieldToken).approve(address(alchemist), 10 ether);
alchemist.deposit(yieldToken, 10 ether, user);
vm.stopPrank();
assertGt(alchemist.totalDeposited(user), 0);
}
}Full Project Template
Clone our starter template for a complete setup:
# Clone template
git clone https://github.com/luxfi/standard-template my-project
cd my-project
# Install dependencies
forge install
# Run tests
forge test