use alloy_primitives::Address;
use std::str::FromStr;
use crate::error::{PolymarketError, Result};
pub const PROTOCOL_NAME: &str = "Polymarket CTF Exchange";
pub const PROTOCOL_VERSION: &str = "1";
pub const ORDER_TYPE: &str = "Order(uint256 salt,address maker,address signer,address taker,uint256 tokenId,uint256 makerAmount,uint256 takerAmount,uint256 expiration,uint256 nonce,uint256 feeRateBps,uint8 side,uint8 signatureType)";
pub const COLLATERAL_TOKEN_DECIMALS: u8 = 6;
pub const CONDITIONAL_TOKEN_DECIMALS: u8 = 6;
const POLYGON_EXCHANGE: &str = "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E";
const POLYGON_NEG_RISK_EXCHANGE: &str = "0xC5d563A36AE78145C45a50134d48A1215220f80a";
const POLYGON_NEG_RISK_ADAPTER: &str = "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296";
const POLYGON_COLLATERAL: &str = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
const POLYGON_CONDITIONAL_TOKENS: &str = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045";
const AMOY_EXCHANGE: &str = "0xdFE02Eb6733538f8Ea35D585af8DE5958AD99E40";
const AMOY_NEG_RISK_EXCHANGE: &str = "0xC5d563A36AE78145C45a50134d48A1215220f80a";
const AMOY_NEG_RISK_ADAPTER: &str = "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296";
const AMOY_COLLATERAL: &str = "0x9c4e1703476e875070ee25b56a58b008cfb8fa78";
const AMOY_CONDITIONAL_TOKENS: &str = "0x69308FB512518e39F9b16112fA8d994F4e2Bf8bB";
#[derive(Debug, Clone)]
pub struct ContractConfig {
pub exchange: Address,
pub neg_risk_exchange: Address,
pub neg_risk_adapter: Address,
pub collateral: Address,
pub conditional_tokens: Address,
}
impl ContractConfig {
fn polygon() -> Self {
Self {
exchange: Address::from_str(POLYGON_EXCHANGE).unwrap(),
neg_risk_exchange: Address::from_str(POLYGON_NEG_RISK_EXCHANGE).unwrap(),
neg_risk_adapter: Address::from_str(POLYGON_NEG_RISK_ADAPTER).unwrap(),
collateral: Address::from_str(POLYGON_COLLATERAL).unwrap(),
conditional_tokens: Address::from_str(POLYGON_CONDITIONAL_TOKENS).unwrap(),
}
}
fn amoy() -> Self {
Self {
exchange: Address::from_str(AMOY_EXCHANGE).unwrap(),
neg_risk_exchange: Address::from_str(AMOY_NEG_RISK_EXCHANGE).unwrap(),
neg_risk_adapter: Address::from_str(AMOY_NEG_RISK_ADAPTER).unwrap(),
collateral: Address::from_str(AMOY_COLLATERAL).unwrap(),
conditional_tokens: Address::from_str(AMOY_CONDITIONAL_TOKENS).unwrap(),
}
}
}
pub fn get_contract_config(chain_id: u64) -> Result<ContractConfig> {
match chain_id {
137 => Ok(ContractConfig::polygon()),
80002 => Ok(ContractConfig::amoy()),
_ => Err(PolymarketError::other(format!(
"Invalid chain ID: {}. Supported: 137 (Polygon), 80002 (Amoy)",
chain_id
))),
}
}
pub fn get_exchange_address(chain_id: u64, neg_risk: bool) -> Result<Address> {
let config = get_contract_config(chain_id)?;
Ok(if neg_risk {
config.neg_risk_exchange
} else {
config.exchange
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_contract_config_polygon() {
let config = get_contract_config(137).unwrap();
assert_eq!(
format!("{:?}", config.exchange).to_lowercase(),
"0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e"
);
}
#[test]
fn test_get_contract_config_amoy() {
let config = get_contract_config(80002).unwrap();
assert_eq!(
format!("{:?}", config.exchange).to_lowercase(),
"0xdfe02eb6733538f8ea35d585af8de5958ad99e40"
);
}
#[test]
fn test_get_contract_config_invalid() {
assert!(get_contract_config(1).is_err());
}
#[test]
fn test_get_exchange_address() {
let addr = get_exchange_address(137, false).unwrap();
assert_eq!(
format!("{:?}", addr).to_lowercase(),
"0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e"
);
let neg_addr = get_exchange_address(137, true).unwrap();
assert_eq!(
format!("{:?}", neg_addr).to_lowercase(),
"0xc5d563a36ae78145c45a50134d48a1215220f80a"
);
}
}