Address Contract Partially Verified
Address
0x259C2FF4e10e7e2B31A2045c93eD8513299c8E04
Balance
0 ETH
Nonce
1
Code Size
6982 bytes
Creator
0x3978a70A...C05B at tx 0x2bdbff72...833353
Indexed Transactions
0 (1 on-chain, 1.7% indexed)
Contract Bytecode
6982 bytes
0x608060405234801561001057600080fd5b50600436106101425760003560e01c806398764d83116100b8578063b8c1db401161007c578063b8c1db401461036b578063d9197c321461037e578063ef7df66b14610387578063f2bc9e051461039a578063f2fde38b146103ad578063f8939e0c146103c057600080fd5b806398764d8314610278578063a4d1776d1461029b578063a5e7f9ea146102a4578063a6a2ee02146102ce578063ae3d5414146102e157600080fd5b80633bb624c21161010a5780633bb624c2146101fb578063582abd121461020e578063715018a614610239578063788cb4d9146102415780637b58c4bd146102545780638da5cb5b1461026757600080fd5b80630e58f7c314610147578063150b7a02146101885780631ecaef43146101c057806329a86c52146101d55780632ce8939a146101e8575b600080fd5b6101756101553660046114a0565b600090815260086020526040902054600160281b900464ffffffffff1690565b6040519081526020015b60405180910390f35b6101a7610196366004611516565b630a85bd0160e11b95945050505050565b6040516001600160e01b0319909116815260200161017f565b6101d36101ce366004611634565b6103d3565b005b6101d36101e336600461168f565b6104a5565b6101756101f63660046114a0565b6104cf565b6101d36102093660046114a0565b6104f0565b600554610221906001600160a01b031681565b6040516001600160a01b03909116815260200161017f565b6101d36104fd565b600254610221906001600160a01b031681565b6101d36102623660046116f5565b610511565b6000546001600160a01b0316610221565b61028b610286366004611760565b6105cf565b60405161017f94939291906117e3565b61017560065481565b6101756102b23660046114a0565b600090815260086020526040902054600160501b900460ff1690565b6101d36102dc366004611890565b61085d565b6103316102ef3660046114a0565b60086020526000908152604090205464ffffffffff80821691600160281b810490911690600160501b810460ff1690600160581b90046001600160a01b031684565b6040805164ffffffffff958616815294909316602085015260ff909116918301919091526001600160a01b0316606082015260800161017f565b600354610221906001600160a01b031681565b61017560045481565b6101d36103953660046114a0565b61087c565b6101d36103a836600461168f565b610889565b6101d36103bb36600461168f565b6108b3565b6101d36103ce3660046118cc565b61092c565b6103db610a9a565b6004548164ffffffffff1611156104315760405162461bcd60e51b8152602060048201526015602482015274109bdc99195c88191bd95cc81b9bdd08195e1a5cdd605a1b60448201526064015b60405180910390fd5b60005b82518110156104a05781600860008584815181106104545761045461198f565b6020026020010151815260200190815260200160002060000160056101000a81548164ffffffffff021916908364ffffffffff1602179055508080610498906119bb565b915050610434565b505050565b6104ad610a9a565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600781815481106104df57600080fd5b600091825260209091200154905081565b6104f8610a9a565b600655565b610505610a9a565b61050f6000610af4565b565b610519610b44565b8281146105685760405162461bcd60e51b815260206004820152601e60248201527f417272617973206d757374206265207468652073616d65206c656e67746800006044820152606401610428565b60005b838110156105bf576105ad8585838181106105885761058861198f565b905060200201358484848181106105a1576105a161198f565b90506020020135610b9d565b806105b7816119bb565b91505061056b565b506105c960018055565b50505050565b60608080806000856001600160401b038111156105ee576105ee611584565b604051908082528060200260200182016040528015610617578160200160208202803683370190505b5090506000866001600160401b0381111561063457610634611584565b60405190808252806020026020018201604052801561065d578160200160208202803683370190505b5090506000876001600160401b0381111561067a5761067a611584565b6040519080825280602002602001820160405280156106a3578160200160208202803683370190505b5090506000886001600160401b038111156106c0576106c0611584565b6040519080825280602002602001820160405280156106e9578160200160208202803683370190505b50905060005b8981101561084c576000600860008d8d8581811061070f5761070f61198f565b602090810292909201358352508181019290925260409081016000208151608081018352905464ffffffffff808216808452600160281b830490911694830194909452600160501b810460ff1692820192909252600160581b9091046001600160a01b0316606082015287519092508790849081106107905761079061198f565b602002602001019064ffffffffff16908164ffffffffff168152505080602001518583815181106107c3576107c361198f565b602002602001019064ffffffffff16908164ffffffffff168152505080604001518483815181106107f6576107f661198f565b602002602001019060ff16908160ff168152505080606001518383815181106108215761082161198f565b6001600160a01b03909216602092830291909101909101525080610844816119bb565b9150506106ef565b509299919850965090945092505050565b610865610a9a565b8051610878906007906020840190611440565b5050565b610884610a9a565b600455565b610891610a9a565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6108bb610a9a565b6001600160a01b0381166109205760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610428565b61092981610af4565b50565b610934610b44565b8685146109835760405162461bcd60e51b815260206004820152601e60248201527f417272617973206d757374206265207468652073616d65206c656e67746800006044820152606401610428565b6000338989898989896040516020016109a297969594939291906119fd565b60408051601f1981840301815291905280516020909101206005549091506109d5906001600160a01b0316828585610d17565b610a155760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964207369676e617475726560781b6044820152606401610428565b60005b88811015610a8557610a738a8a83818110610a3557610a3561198f565b90506020020135898984818110610a4e57610a4e61198f565b90506020020135888885818110610a6757610a6761198f565b90506020020135610dcd565b80610a7d816119bb565b915050610a18565b5050610a9060018055565b5050505050505050565b6000546001600160a01b0316331461050f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610428565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600260015403610b965760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610428565b6002600155565b60008281526008602052604090206004548154600160281b900464ffffffffff1610610c0b5760405162461bcd60e51b815260206004820152601a60248201527f546f6b656e20697320616c7265616479206d61786564206f75740000000000006044820152606401610428565b600354604051632142170760e11b8152336004820152306024820152604481018590526001600160a01b03909116906342842e0e90606401600060405180830381600087803b158015610c5d57600080fd5b505af1158015610c71573d6000803e3d6000fd5b5050600254604051635209071360e01b8152600481018690523360248201526001600160a01b03909116925063520907139150604401600060405180830381600087803b158015610cc157600080fd5b505af1158015610cd5573d6000803e3d6000fd5b50508254600160581b33027fff0000000000000000000000000000000000000000ffffffffffff000000000090911664ffffffffff4216171790925550505050565b6000610daf610d73856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061117892505050565b6001600160a01b0316856001600160a01b0316149050949350505050565b60008381526008602052604090208054600160581b90046001600160a01b03163314610e275760405162461bcd60e51b81526020600482015260096024820152682737ba1037bbb732b960b91b6044820152606401610428565b6006548154610e3d9064ffffffffff1642611a43565b1015610e8b5760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e2063616e206e6f74206c65617665207761722079657400000000006044820152606401610428565b8054600160501b900460ff168214610ee55760405162461bcd60e51b815260206004820152601b60248201527f426174746c6520696e64657820646f6573206e6f74206d6174636800000000006044820152606401610428565b805464ffffffffff19168082556001908290600a90610f0f908490600160501b900460ff16611a56565b92506101000a81548160ff021916908360ff160217905550610f6b848460078460000160059054906101000a900464ffffffffff1664ffffffffff1681548110610f5b57610f5b61198f565b906000526020600020015461119e565b1561108857604080516001808252818301909252600091602080830190803683370190505090508481600081518110610fa657610fa661198f565b602090810291909101015281547fff0000000000000000000000000000000000000000ffffffffffffffffffffff16825560035460405163b80f55c960e01b81526001600160a01b039091169063b80f55c990611007908490600401611a6f565b600060405180830381600087803b15801561102157600080fd5b505af1158015611035573d6000803e3d6000fd5b5050835460408051898152600160281b90920464ffffffffff1660208301527f735b6ee0baa0e267b335b9cbe4a627617e13b2cd15bcf0382430f8c73f356a0e935001905060405180910390a1506105c9565b6003546040516323b872dd60e01b8152306004820152336024820152604481018690526001600160a01b03909116906323b872dd90606401600060405180830381600087803b1580156110da57600080fd5b505af11580156110ee573d6000803e3d6000fd5b5050825461110e9250600160281b900464ffffffffff1690506001611ab3565b815469ffffffffff00000000001916600160281b64ffffffffff928316810291909117808455604080518881529290910490921660208201527fc6e154d143a863e2cce9664b681e1abf3260e6350b653095c731bec6f16dccde910160405180910390a150505050565b600080600061118785856111ed565b9150915061119481611232565b5090505b92915050565b600080606485856040516020016111bf929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c6111e29190611ad8565b909211949350505050565b60008082516041036112235760208301516040840151606085015160001a6112178782858561137c565b9450945050505061122b565b506000905060025b9250929050565b600081600481111561124657611246611afa565b0361124e5750565b600181600481111561126257611262611afa565b036112af5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610428565b60028160048111156112c3576112c3611afa565b036113105760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610428565b600381600481111561132457611324611afa565b036109295760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610428565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156113b35750600090506003611437565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611407573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661143057600060019250925050611437565b9150600090505b94509492505050565b82805482825590600052602060002090810192821561147b579160200282015b8281111561147b578251825591602001919060010190611460565b5061148792915061148b565b5090565b5b80821115611487576000815560010161148c565b6000602082840312156114b257600080fd5b5035919050565b80356001600160a01b03811681146114d057600080fd5b919050565b60008083601f8401126114e757600080fd5b5081356001600160401b038111156114fe57600080fd5b60208301915083602082850101111561122b57600080fd5b60008060008060006080868803121561152e57600080fd5b611537866114b9565b9450611545602087016114b9565b93506040860135925060608601356001600160401b0381111561156757600080fd5b611573888289016114d5565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126115ab57600080fd5b813560206001600160401b03808311156115c7576115c7611584565b8260051b604051601f19603f830116810181811084821117156115ec576115ec611584565b60405293845285810183019383810192508785111561160a57600080fd5b83870191505b8482101561162957813583529183019190830190611610565b979650505050505050565b6000806040838503121561164757600080fd5b82356001600160401b0381111561165d57600080fd5b6116698582860161159a565b925050602083013564ffffffffff8116811461168457600080fd5b809150509250929050565b6000602082840312156116a157600080fd5b6116aa826114b9565b9392505050565b60008083601f8401126116c357600080fd5b5081356001600160401b038111156116da57600080fd5b6020830191508360208260051b850101111561122b57600080fd5b6000806000806040858703121561170b57600080fd5b84356001600160401b038082111561172257600080fd5b61172e888389016116b1565b9096509450602087013591508082111561174757600080fd5b50611754878288016116b1565b95989497509550505050565b6000806020838503121561177357600080fd5b82356001600160401b0381111561178957600080fd5b611795858286016116b1565b90969095509350505050565b600081518084526020808501945080840160005b838110156117d857815164ffffffffff16875295820195908201906001016117b5565b509495945050505050565b6080815260006117f660808301876117a1565b60208382038185015261180982886117a1565b8481036040860152865180825282880193509082019060005b8181101561184157845160ff1683529383019391830191600101611822565b50508481036060860152855180825290820192508186019060005b818110156118815782516001600160a01b03168552938301939183019160010161185c565b50929998505050505050505050565b6000602082840312156118a257600080fd5b81356001600160401b038111156118b857600080fd5b6118c48482850161159a565b949350505050565b6000806000806000806000806080898b0312156118e857600080fd5b88356001600160401b03808211156118ff57600080fd5b61190b8c838d016116b1565b909a50985060208b013591508082111561192457600080fd5b6119308c838d016116b1565b909850965060408b013591508082111561194957600080fd5b6119558c838d016116b1565b909650945060608b013591508082111561196e57600080fd5b5061197b8b828c016114d5565b999c989b5096995094979396929594505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016119cd576119cd6119a5565b5060010190565b60006001600160fb1b038311156119ea57600080fd5b8260051b80838637939093019392505050565b6bffffffffffffffffffffffff198860601b1681526000611a36611a2f611a28601485018a8c6119d4565b87896119d4565b84866119d4565b9998505050505050505050565b81810381811115611198576111986119a5565b60ff8181168382160190811115611198576111986119a5565b6020808252825182820181905260009190848201906040850190845b81811015611aa757835183529284019291840191600101611a8b565b50909695505050505050565b64ffffffffff818116838216019080821115611ad157611ad16119a5565b5092915050565b600082611af557634e487b7160e01b600052601260045260246000fd5b500690565b634e487b7160e01b600052602160045260246000fdfea264697066735822122098aae522cbae28e01038c27e9bd433dc46406e6e924aa60ef668dca3f2a2c14864736f6c63430008130033
Verified Source Code Partial Match
Compiler: v0.8.19+commit.7dd6d404
EVM: paris
Optimization: Yes (200 runs)
WarStaking.sol 1076 lines
// SPDX-License-Identifier: MIT
// War by ATS. Written by NiftyLabs (https://niftylabs.dev/).
//,,,,,,******,*************////*********,,,,*************//**///////((((((((((((((((((((((((((((((((#
//***********,,,,,************///*************************//////((((((((((########################%#%#
//,,,,,,,,,,,,,,,,,,,,,,**************************,******///((((((((((((((####((((###############%%%%%
//,,,,,,,,,,,,,,,,,,,,,,,/*************,**********************//(((((((((((((((((((((############%%%%%
//,,,,,,,,,,,,,,,,,,,,(##.#**************,,,,,,,,,,,*,,,*********/////((((((((((((((############%%%%%%
//.,,,,,,,,,,,,,,,,,,,,,(#,#,#(/*********,,,,,#%%%%%%%%%(,,**********////(((((((((((##################
//..,,,,,,,,,,,,,,,,,,,,, */,.####********,,/%#%%%%%%%%%%%***********///((//(((((((###############%%%%
//.....,,,,,,,,,,,,,,,,,,,*/.#(*/#(##,******%%%%%%%%%%%%%%%%***/////(((/////////(((############%#%%%%%
//........,,,,,,,,,,,,,,,,,,,,,#(##(###******%%%%%%%%%%%%%%#*******//////////////((((##########%%%%%%%
//..........,,,,,,,,,,,,,,,,,,,,,,, ######*#%%%%%%%%%%%%%%%%%%%%/*****////////////((((##########%%%%%
//............,,,,,,,,,,,,,,,,,,,,,,##########%%%%%%%%%%%%%%%%%%%%%%%(***/////(((((((((((##########%%%
//.............,,,,,,,,,,,,,,,,,###############%%%%%%%%%%%%%%%%%%%%%%%&%////////((((((((((((((#####%%%
//..............,,,,,,,,,,,,,,,,,,,*##########%#%%%%%%%%%%%%%%%%%%%%%%%&&*/////////////////((((#######
//................,,,,,,,,,,,,,,,,,#############%##%%%%%%%%%%%%%%%%%%%%&&&#*////////(((((((((((((((###
//.................,,,,,,,,,,,,,,,############%%%%%%%%%%%%%%%%%%%%%%%%%&&&&&(//////////(((((/((((###((
//....................,,,,,,,,,,*#############%%%%%%%%%%%%#%%%%%%%%%%%&&&&&&&&*////////(((((((((#####(
//.........................,,,,,(#############%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&&*/////////(((((((((((((
//........................,,,,,(((##############%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&%/(((((((((((#######(((
//........................,,,,(((#######,*#######%%%%%%%%%%%%%%%%%%%**%&&&&&&&&&&///(((((((((((######(
//..........................(((((#####(,,(#####%%%%%%%%%%%%%%%%%%%%%%***%&&&&&&&&&%///(((((((((((###(#
//........................,((((((#####*,,,########%%%%%%%%%%%%%%%%%(%%%**%&&&&&&&&&#///(((((((((((####
//........................*(((((((###/,,,,,#####%%%#%%%%%%%%%%%%%%%%%%&&%/&&&&&&&&&&%//(((((((((((((##
//........................((((((((##*,,,,,,,#######%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&///((((((((((#(((
//.......................,/(((((((#,,,,,,,,,######%%%%%%%%%%%%%%%%%%#**(/**/&&&&&&&&&///((((//((((((((
//.......................///(((((*.,,,,,,,,,,####%%#%%%%%%%%%%%%%%%%%***/***/&&&&&&&&////((((((((((#((
//.......................///((((..,,,,,,,,,,*#####%%%%%%%%%%%%%%%%%&&**///////&&&&&&#//(((((((((((###(
//.......................///((/..,,,,,,,,,,,#####%%%%%%%%%%%%%%%%%%%&%*///////&&&&&&%(((((((((((((####
//.......................///((.,,,,,,,,,,,,####%%%%%%%%%%%%%%%%%%%%%&&#//////&&&&&&&&((((((((((((#####
//......................,///((.,,,,,,,,,,,#####%%%%%%%%%%%%%%%%%%%%&&&&/////&&/&&&&&&(((((((((((######
//......................////(*(/,,,,,,,,,/#####%%%%%%%%#***%%%%%%%%&&&&%///////&&&&&&((((((((#########
//.......................////((,,,,,,,,,,#######%%%%%%*****%%%%%%&%%&&&%/////((&&&&&&&(((##(##########
//.......................*,.,..,,,,,,,,,,######%%%%%%*******%%%%%%&&&&&///(((((&&&&&&%(###############
//.. .................././.*../,,,,,,,,,,###%%%%%%%%*********%&&&&&&&&&//((((((%(&&&&(################
//....................*/*,,/(((((((#,,,,,/##%%%%%%%%******////&&&&&&&&&/((((((((&#&###################
//....................,,,,,,,((((((#,,,,,*##%%%%%%%%%***//////%&&&&&&&&%(((((((######################%
//...................../**/*((((((####*****%%%%%%%%%%(////////%&&&&&&&&#(((((####################%%%%%
//..................,,,,,,,,,,,,,*#####*****%%%%%%%%%%////////&&&&&&&&&((((######################%%%%%
//................,,,,,,,,,,,,,*************/%%%%%%%%&/////((((&&&&&&&&#(######################%%%%%%%
//..........,.,,,,,,,,,,,,,******/*/**/*//**(#%%%%%&%&/%((((((#%&&&&&&&##%##(################%%%%%%%%%
//*//*////,*/((/#,(/**/(#**(##(%#%%%%%%%%%%&%&&&&&&&&&&&&&&%&&&&&@&&@@@&@&&&&@&@&@&&@@&&&&&&%&%%%%&%&%
//(##############%%%%%%%#%%%%%%%&%&&&&&&&&&&&&&&&&&@&&&@&@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&&&&&@&&&@@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//%%%%%%%%%%%&&%&&&&&&&&&&&&&&&&&&&&&&&@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// File: @openzeppelin/contracts/utils/math/Math.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
// File: @openzeppelin/contracts/utils/Strings.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.0;
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV // Deprecated in v4.8
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature` or error string. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*
* _Available since v4.3._
*/
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
/// @solidity memory-safe-assembly
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*
* _Available since v4.2._
*/
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*
* _Available since v4.3._
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
// 32 is the length in bytes of hash,
// enforced by the type signature above
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
/**
* @dev Returns an Ethereum Signed Message, created from `s`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
// File: @openzeppelin/contracts/utils/Context.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// File: @openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: War.sol
pragma solidity ^0.8.18;
interface WarBonds {
function burnForAddress(uint256 _id, address _address) external;
}
interface Rota {
function ownerOf(uint256 tokenId) external view returns (address);
function safeTransferFrom(address from, address to, uint256 tokenId) external payable;
function transferFrom(address from, address to, uint256 tokenId) external payable;
function burn(uint256[] memory tokenIds) external;
function setApprovalForAll(address operator, bool _approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
contract WarStaking is Ownable, IERC721Receiver, ReentrancyGuard {
address public WARBONDS_CONTRACT = 0xcAcb0a5bb1f52F00a14bDA0dc85dE81392B2892B;
address public ROTA_CONTRACT = 0xDfB29501b42f63A947Ddc5249F185D6BcBE6986f;
uint256 public MAX_TYPE = 4;
address public SIGNER = 0x2f2A13462f6d4aF64954ee84641D265932849b64;
uint256 public warTime = 48 hours;
uint256[] public burnRates = [15, 30, 45, 60, 60];
struct TokenData {
uint40 time;
uint40 border;
uint8 battlesCompleted;
address owner;
}
mapping(uint256 => TokenData) public tokenToData;
event WarLost(uint256 tokenId, uint256 valueAtBurn);
event WarWon(uint256 tokenId, uint256 newValue);
function goToWar(uint256[] calldata tokenIds, uint256[] calldata warBondIds) external nonReentrant {
require(tokenIds.length == warBondIds.length, "Arrays must be the same length");
for(uint256 i = 0; i < tokenIds.length; i++)
_goToWar(tokenIds[i], warBondIds[i]);
}
function _goToWar(uint256 tokenId, uint256 warBondId) internal {
TokenData storage data = tokenToData[tokenId];
require(data.border < MAX_TYPE, "Token is already maxed out");
Rota(ROTA_CONTRACT).safeTransferFrom(msg.sender, address(this), tokenId);
WarBonds(WARBONDS_CONTRACT).burnForAddress(warBondId, msg.sender);
data.time = uint40(block.timestamp);
data.owner = msg.sender;
}
function leaveWar(uint256[] calldata tokenIds, uint256[] calldata randomNumbers, uint256[] calldata battleIndices, bytes calldata signature) external nonReentrant {
require(tokenIds.length == randomNumbers.length, "Arrays must be the same length");
bytes32 hash = keccak256(abi.encodePacked(msg.sender, tokenIds, randomNumbers, battleIndices));
require(_verifySignature(SIGNER, hash, signature), "Invalid signature");
for(uint256 i = 0; i < tokenIds.length; i++)
_leaveWar(tokenIds[i], randomNumbers[i], battleIndices[i]);
}
function _leaveWar(uint256 tokenId, uint256 randomNumber, uint256 battleIndex) internal {
TokenData storage data = tokenToData[tokenId];
require(msg.sender == data.owner, "Not owner");
require(block.timestamp - data.time >= warTime, "Token can not leave war yet");
require(battleIndex == data.battlesCompleted, "Battle index does not match");
data.time = 0;
data.battlesCompleted += 1;
if(diedAtWar(tokenId, randomNumber, burnRates[data.border])) {
uint256[] memory tokenIds = new uint256[](1);
tokenIds[0] = tokenId;
data.owner = address(0);
Rota(ROTA_CONTRACT).burn(tokenIds);
emit WarLost(tokenId, data.border);
} else {
Rota(ROTA_CONTRACT).transferFrom(address(this), msg.sender, tokenId);
data.border = data.border + 1;
emit WarWon(tokenId, data.border);
}
}
function _verifySignature(address _signer, bytes32 _hash, bytes calldata _signature) internal pure returns (bool) {
return _signer == ECDSA.recover(ECDSA.toEthSignedMessageHash(_hash), _signature);
}
function diedAtWar(uint256 tokenId, uint256 random, uint256 burnRate) internal pure returns (bool) {
uint256 randomNumber = uint256(keccak256(abi.encodePacked(tokenId, random))) % 100;
return randomNumber < burnRate;
}
function getBorderNumber(uint256 tokenId) public view returns (uint256) {
TokenData storage data = tokenToData[tokenId];
return data.border;
}
function getNumberOfBattles(uint256 tokenId) public view returns (uint256) {
TokenData storage data = tokenToData[tokenId];
return data.battlesCompleted;
}
function getTokenDataFor(uint256[] calldata tokenIds) public view returns (uint40[] memory, uint40[] memory, uint8[] memory, address[] memory) {
uint40[] memory times = new uint40[](tokenIds.length);
uint40[] memory borders = new uint40[](tokenIds.length);
uint8[] memory battlesCompleted = new uint8[](tokenIds.length);
address[] memory owners = new address[](tokenIds.length);
for(uint256 i = 0; i < tokenIds.length; i++) {
TokenData memory data = tokenToData[tokenIds[i]];
times[i] = data.time;
borders[i] = data.border;
battlesCompleted[i] = data.battlesCompleted;
owners[i] = data.owner;
}
return (times, borders, battlesCompleted, owners);
}
function changeWarTime(uint256 _time) public onlyOwner {
warTime = _time;
}
function overrideBorder(uint256[] memory tokenId, uint40 _border) public onlyOwner {
require(_border <= MAX_TYPE, "Border does not exist");
for(uint256 i = 0; i < tokenId.length; i++)
tokenToData[tokenId[i]].border = _border;
}
function setBurnRates(uint256[] memory _rates) public onlyOwner {
burnRates = _rates;
}
function setRotaContract(address _addr) public onlyOwner {
ROTA_CONTRACT = _addr;
}
function setWarBondsContract(address _addr) public onlyOwner {
WARBONDS_CONTRACT = _addr;
}
function setMaxWarType(uint256 _max) public onlyOwner {
MAX_TYPE = _max;
}
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external pure override returns (bytes4) {
return IERC721Receiver.onERC721Received.selector;
}
}
Read Contract
MAX_TYPE 0xd9197c32 → uint256
ROTA_CONTRACT 0xb8c1db40 → address
SIGNER 0x582abd12 → address
WARBONDS_CONTRACT 0x788cb4d9 → address
burnRates 0x2ce8939a → uint256
getBorderNumber 0x0e58f7c3 → uint256
getNumberOfBattles 0xa5e7f9ea → uint256
getTokenDataFor 0x98764d83 → uint40[], uint40[], uint8[], address[]
onERC721Received 0x150b7a02 → bytes4
owner 0x8da5cb5b → address
tokenToData 0xae3d5414 → uint40, uint40, uint8, address
warTime 0xa4d1776d → uint256
Write Contract 10 functions
These functions modify contract state and require a wallet transaction to execute.
changeWarTime 0x3bb624c2
uint256 _time
goToWar 0x7b58c4bd
uint256[] tokenIds
uint256[] warBondIds
leaveWar 0xf8939e0c
uint256[] tokenIds
uint256[] randomNumbers
uint256[] battleIndices
bytes signature
overrideBorder 0x1ecaef43
uint256[] tokenId
uint40 _border
renounceOwnership 0x715018a6
No parameters
setBurnRates 0xa6a2ee02
uint256[] _rates
setMaxWarType 0xef7df66b
uint256 _max
setRotaContract 0x29a86c52
address _addr
setWarBondsContract 0xf2bc9e05
address _addr
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
This address has 1 on-chain transactions, but only 1.7% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →