Address
- Address
- 0xb34540b543b7b6cfa7c18299657f07ce29ec9622
- Type
- contract
- Balance
- 0 tMIDX (0 wei)
- Nonce
- 1
- Code size
- 1,663 bytes
Contract
Source code ✓ verified
- Contract
- FxTradeRecorder
- Compiler
- solc 0.8.36+commit.8a079791
- Optimizer
- enabled, 200 runs
- Verified
- 2026-09-21 18:20:13 UTC
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/// @title FxTradeRecorder
/// @notice Append-only, on-chain log of FX trade outcomes from the MIDX maker, so that BOTH fills and
/// rejects are visible on the testnet explorer as transactions with decoded event logs. A fill
/// moves nothing by itself, and a reject moves nothing at all, so without this each would leave
/// no on-chain trace — this contract turns each outcome into an event.
///
/// Records only: it does NOT custody or move any tokens. The maker's recorder key (owner) submits
/// one `recordFill` / `recordReject` per execution report. Testnet use only.
///
/// Numeric conventions: `priceE8` and `qtyE8` are fixed-point scaled by 1e8 (8 decimals), which is
/// lossless for FX prices (<=5 dp), JPY (3 dp), metals (2 dp) and the quantities used here.
/// `clOrdId` is the ASCII ClOrdID packed into bytes32 (spec caps ClOrdID at 24 chars). `side` is
/// 1=buy, 2=sell (taker side). `reason` is the FIX OrdRejReason (1=unknown symbol, 6=duplicate,
/// 99=other, which includes last-look).
contract FxTradeRecorder {
address public owner;
uint256 public fillCount;
uint256 public rejectCount;
event Fill(
uint256 indexed seq,
bytes32 indexed clOrdId,
string symbol,
uint8 side,
uint256 qtyE8,
uint256 priceE8,
string currency,
string execId,
uint64 timestamp
);
event Reject(
uint256 indexed seq,
bytes32 indexed clOrdId,
string symbol,
uint8 side,
uint256 qtyE8,
uint8 reason,
string text,
uint64 timestamp
);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
modifier onlyOwner() {
require(msg.sender == owner, "not owner");
_;
}
constructor(address _owner) {
owner = _owner;
emit OwnershipTransferred(address(0), _owner);
}
function recordFill(
bytes32 clOrdId,
string calldata symbol,
uint8 side,
uint256 qtyE8,
uint256 priceE8,
string calldata currency,
string calldata execId,
uint64 timestamp
) external onlyOwner {
emit Fill(++fillCount, clOrdId, symbol, side, qtyE8, priceE8, currency, execId, timestamp);
}
function recordReject(
bytes32 clOrdId,
string calldata symbol,
uint8 side,
uint256 qtyE8,
uint8 reason,
string calldata text,
uint64 timestamp
) external onlyOwner {
emit Reject(++rejectCount, clOrdId, symbol, side, qtyE8, reason, text, timestamp);
}
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "zero owner");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
ABI
[
{
"type": "constructor",
"inputs": [
{
"name": "_owner",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "nonpayable"
},
{
"name": "Fill",
"type": "event",
"inputs": [
{
"name": "seq",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "clOrdId",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "symbol",
"type": "string",
"indexed": false,
"internalType": "string"
},
{
"name": "side",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
},
{
"name": "qtyE8",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "priceE8",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "currency",
"type": "string",
"indexed": false,
"internalType": "string"
},
{
"name": "execId",
"type": "string",
"indexed": false,
"internalType": "string"
},
{
"name": "timestamp",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "Reject",
"type": "event",
"inputs": [
{
"name": "seq",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "clOrdId",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "symbol",
"type": "string",
"indexed": false,
"internalType": "string"
},
{
"name": "side",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
},
{
"name": "qtyE8",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "reason",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
},
{
"name": "text",
"type": "string",
"indexed": false,
"internalType": "string"
},
{
"name": "timestamp",
"type": "uint64",
"indexed": false,
"internalType": "uint64"
}
],
"anonymous": false
},
{
"name": "fillCount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "recordFill",
"type": "function",
"inputs": [
{
"name": "clOrdId",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "symbol",
"type": "string",
"internalType": "string"
},
{
"name": "side",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "qtyE8",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "priceE8",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "currency",
"type": "string",
"internalType": "string"
},
{
"name": "execId",
"type": "string",
"internalType": "string"
},
{
"name": "timestamp",
"type": "uint64",
"internalType": "uint64"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "recordReject",
"type": "function",
"inputs": [
{
"name": "clOrdId",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "symbol",
"type": "string",
"internalType": "string"
},
{
"name": "side",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "qtyE8",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "reason",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "text",
"type": "string",
"internalType": "string"
},
{
"name": "timestamp",
"type": "uint64",
"internalType": "uint64"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "rejectCount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
}
]Transactions (12 indexed)
page 1 / 1
Temporary placeholder infrastructure for chain registration.
Not a production network - state may be reset without notice.