Erbie Bridge#
Contract Overview#
Erbie Bridge is a multi-token bridge contract that supports locking and emergency withdrawal of both XL and L tokens. The contract is implemented based on OpenZeppelin’s upgradeable contract framework with the following core features:
Upgradeability: Secure upgrades through UUPS upgrade pattern
Access Control: Owner permission management based on OwnableUpgradeable
Pause Mechanism: Support for global pause/unpause operations
Token Lock Records: Tracking user’s locked token information
Core Dependencies and Interfaces#
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; // UUPS upgrade
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; // ERC20 interface
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; // Initialization
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; // Owner permissions
import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol"; // Pause functionality
import "./interfaces/IErbieBridge.sol"; // Custom interface
Core Variables and Structs#
Token Addresses#
IERC20 public XL; // XL token interface
IERC20 public L; // L token interface
Lock Counter and Version Number#
uint256 public lockCounter; // Lock record counter
uint256 public version; // Contract version number
Lock Record Structure#
struct LockInfo {
address user; // User address
address tokenAddress; // Locked token address
uint256 amount; // Lock amount
bool withdrawn; // Whether withdrawn
}
mapping(uint256 => LockInfo) public lockRecords; // Lock records mapping
Core Function Details#
1. Initialize Function#
function initialize(
address _XL,
address _L,
address initialOwner
) external initializer {
require(_XL != address(0) && _L != address(0), "Invalid token address");
__Ownable_init(initialOwner);
__Pausable_init();
__UUPSUpgradeable_init();
XL = IERC20(_XL);
L = IERC20(_L);
version = 1;
lockCounter = 0;
}
Function: Contract initialization, setting token addresses, owner, and initial state
- Key Points:
Validate token address legitimacy
Initialize parent contracts (permissions, pause, upgrade)
Initialize counter and version number
2. Token Address Management#
function setXLTokenAddress(address _XL) public onlyOwner {
require(_XL != address(0), "Cannot set to the zero address");
XL = IERC20(_XL);
}
function setLTokenAddress(address _L) public onlyOwner {
require(_L != address(0), "Cannot set to the zero address");
L = IERC20(_L);
}
Function: Allows owner to update token contract addresses
Risk: Malicious modification of token addresses could lead to fund loss
3. User Token Locking#
function lock(
address tokenAddress,
uint256 amount
) external payable override whenNotPaused {
require(
tokenAddress == address(XL) || tokenAddress == address(L),
"Invalid token address"
);
require(amount > 0, "Amount must be greater than 0");
IERC20 token = IERC20(tokenAddress);
require(
token.allowance(msg.sender, address(this)) >= amount,
"Allowance too low"
);
token.transferFrom(msg.sender, address(this), amount);
lockCounter++;
uint256 currentLockId = lockCounter;
lockRecords[currentLockId] = LockInfo(
msg.sender,
tokenAddress,
amount,
false
);
emit TokenLocked(
msg.sender,
tokenAddress,
amount,
currentLockId,
block.timestamp
);
}
Function: Users lock specified tokens into the contract
- Key Logic:
Verify if token is XL or L
Check token amount validity
Verify user allowance
Transfer tokens and record lock information
Event: TokenLocked records lock details
4. Emergency Token Withdrawal#
function emergencyWithdraw(
address tokenAddress,
address to,
uint256 amount
) public override onlyOwner {
IERC20 token = IERC20(tokenAddress);
token.transfer(to, amount);
}
Function: Owner emergency withdraws tokens to specified address
- Risks:
Can withdraw any token (including unsupported tokens)
Need to ensure owner permission security
5. Upgrade and Permission Control#
function _authorizeUpgrade(
address newImplementation
) internal override onlyOwner {
require(
newImplementation != address(0),
"Cannot upgrade to the zero address"
);
}
Function: Authorize upgrade to new implementation contract
Restriction: Only owner can execute, and new address must be valid
6. Pause and Unpause#
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
Function: Owner controls contract pause status
7. Version Management#
function setVersion(uint256 newVersion) external onlyOwner {
require(newVersion > 0, "Version must be greater than 0");
version = newVersion;
}
Function: Update contract version number