Address Contract Partially Verified
Address
0xBC86727E770de68B1060C91f6BB6945c73e10388
Balance
0 ETH
Nonce
3
Code Size
10212 bytes
Creator
0xabbaFbCA...6fcc at tx 0x00a6d26c...614046
Indexed Transactions
0
Contract Bytecode
10212 bytes
0x60606040526004361061017c5763ffffffff60e060020a60003504166306fdde038114610181578063095ea7b31461020b57806310bd6d2b1461024157806318160ddd1461027057806319062b8f146102955780631f4a5c32146102ad57806323b872dd146102c3578063313ce567146102eb57806349bf2caf146103145780634f438a121461032a5780635a30b194146103495780636381ca261461035c57806366188463146103725780636875c3191461039457806370a08231146103aa578063735631ad146103c95780637453a417146103df57806391a89712146103f2578063935e97c21461041157806395d89b411461042d578063a9059cbb14610440578063a9dd689514610462578063bfd3c5fa14610478578063c01a8c841461048e578063cc94d923146104a4578063d4e678b8146104dd578063d73dd623146104f3578063d8ec696f14610515578063dd62ed3e14610528578063f1bd59781461054d578063fb0b6b6d14610560578063fb8a5f1c14610576575b600080fd5b341561018c57600080fd5b6101946105a9565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156101d05780820151838201526020016101b8565b50505050905090810190601f1680156101fd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561021657600080fd5b61022d600160a060020a03600435166024356105e0565b604051901515815260200160405180910390f35b341561024c57600080fd5b61025461064d565b604051600160a060020a03909116815260200160405180910390f35b341561027b57600080fd5b610283610665565b60405190815260200160405180910390f35b34156102a057600080fd5b6102ab60043561066b565b005b34156102b857600080fd5b6102ab600435610680565b34156102ce57600080fd5b61022d600160a060020a0360043581169060243516604435610692565b34156102f657600080fd5b6102fe6106c8565b60405160ff909116815260200160405180910390f35b341561031f57600080fd5b6102ab6004356106cd565b341561033557600080fd5b6102ab60043560ff602435166044356106df565b341561035457600080fd5b6102546106f8565b341561036757600080fd5b6102ab600435610710565b341561037d57600080fd5b61022d600160a060020a0360043516602435610722565b341561039f57600080fd5b6102ab60043561081c565b34156103b557600080fd5b610283600160a060020a036004351661082e565b34156103d457600080fd5b6102ab60043561084d565b34156103ea57600080fd5b61025461085f565b34156103fd57600080fd5b6102ab600160a060020a0360043516610877565b341561041c57600080fd5b6102ab6004356024356044356108f0565b341561043857600080fd5b610194610904565b341561044b57600080fd5b61022d600160a060020a036004351660243561093b565b341561046d57600080fd5b6102ab60043561096f565b341561048357600080fd5b6102ab600435610981565b341561049957600080fd5b6102ab600435610993565b34156104af57600080fd5b610283600160a060020a03600435811690602435906044359060643581169060843581169060a435166109a5565b34156104e857600080fd5b6102ab6004356109c0565b34156104fe57600080fd5b61022d600160a060020a03600435166024356109d2565b341561052057600080fd5b610254610a76565b341561053357600080fd5b610283600160a060020a0360043581169060243516610a8e565b341561055857600080fd5b610254610ab9565b341561056b57600080fd5b6102ab600435610ad1565b341561058157600080fd5b610283600160a060020a03600435811690602435906044359060643581169060843516610ae3565b60408051908101604052600c81527f496e6b2050726f746f636f6c0000000000000000000000000000000000000000602082015281565b600160a060020a03338116600081815260026020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a35060015b92915050565b7329a4b44364a8bcb6e4d9dd60c222ccaca286ebf281565b60015490565b61067d8161067883610afe565b610b43565b50565b61067d8161068d83610c37565b610c62565b600030600160a060020a031683600160a060020a0316141515156106b557600080fd5b6106c0848484610cc4565b949350505050565b601281565b61067d816106da83610e44565b610e6c565b6106f3836106ec85610e44565b8484610ee8565b505050565b73a13febeede2b2924ce8b27c1512874d3576fec1681565b61067d8161071d83610f76565b610fa1565b600160a060020a0333811660009081526002602090815260408083209386168352929052908120548083111561077f57600160a060020a0333811660009081526002602090815260408083209388168352929052908120556107b6565b61078f818463ffffffff610fe216565b600160a060020a033381166000908152600260209081526040808320938916835292905220555b600160a060020a0333811660008181526002602090815260408083209489168084529490915290819020547f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925915190815260200160405180910390a35060019392505050565b61067d8161082983610c37565b610ff4565b600160a060020a0381166000908152602081905260409020545b919050565b61067d8161085a83610e44565b611055565b730746d0b67bed258d94d06b15859df8dbd990ec3d81565b600160a060020a038116151561088c57600080fd5b33600160a060020a031681600160a060020a0316141515156108ad57600080fd5b80600160a060020a031633600160a060020a03167f663f26703bd344e9f8d6bc0b1f4e4fa06a81703a4eb10c90e62d60044e8be4ca60405160405180910390a350565b6106f3836108fd85610f76565b84846110cf565b60408051908101604052600381527f584e4b0000000000000000000000000000000000000000000000000000000000602082015281565b600030600160a060020a031683600160a060020a03161415151561095e57600080fd5b610968838361127f565b9392505050565b61067d8161097c83610c37565b611391565b61067d8161098e83610e44565b611434565b61067d816109a083610e44565b61148e565b60006109b5878787878787611540565b979650505050505050565b61067d816109cd83610c37565b611758565b600160a060020a033381166000908152600260209081526040808320938616835292905290812054610a0a908363ffffffff61180716565b600160a060020a0333811660008181526002602090815260408083209489168084529490915290819020849055919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591905190815260200160405180910390a350600192915050565b73c5ba7157b5b69b0fae9332f30719eecd7964948681565b600160a060020a03918216600090815260026020908152604080832093909416825291909152205490565b73c1dc1e5c3970e22201c5dab0841abb2dd6499d3f81565b61067d81610ade83610f76565b611816565b6000610af486868686866000611540565b9695505050505050565b6000610b098261185a565b805490915033600160a060020a0390811691161480610b385750600181015433600160a060020a039081169116145b151561084857600080fd5b6000806004600384015460a060020a900460ff166011811115610b6257fe5b14610b6c57600080fd5b610b8083610b7b856003611876565b611ad6565b1515610b8b57600080fd5b6005830154610ba190600263ffffffff611aff16565b6005840154909250610bb9908363ffffffff610fe216565b9050837fa06caae8c696e5deb33f685024044b74125cb932e11521aef47de748321657c4838360405191825260208201526040908101905180910390a28254610c0b90600160a060020a031683611b16565b506001830154610c2490600160a060020a031682611b16565b50610c3184846001611b3b565b50505050565b6000610c428261185a565b600181015490915033600160a060020a0390811691161461084857600080fd5b6002600382015460a060020a900460ff166011811115610c7e57fe5b14610c8857600080fd5b610c9781610b7b836000611876565b1515610ca257600080fd5b6001810154610cc09083908390600b90600160a060020a0316611c11565b5050565b6000600160a060020a0383161515610cdb57600080fd5b600160a060020a038416600090815260208190526040902054821115610d0057600080fd5b600160a060020a0380851660009081526002602090815260408083203390941683529290522054821115610d3357600080fd5b600160a060020a038416600090815260208190526040902054610d5c908363ffffffff610fe216565b600160a060020a038086166000908152602081905260408082209390935590851681522054610d91908363ffffffff61180716565b600160a060020a0380851660009081526020818152604080832094909455878316825260028152838220339093168252919091522054610dd7908363ffffffff610fe216565b600160a060020a03808616600081815260026020908152604080832033861684529091529081902093909355908516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060019392505050565b6000610e4f8261185a565b805490915033600160a060020a0390811691161461084857600080fd5b6002600382015460a060020a900460ff166011811115610e8857fe5b14610e9257600080fd5b610ea181610b7b836001611876565b1515610eac57600080fd5b610eb7816003611f57565b817f61e60550bebc2b32282d4baacb9094d9c194d45912cea3e6b10440d24bf5d0fa60405160405180910390a25050565b6000600384015460a060020a900460ff166011811115610f0457fe5b14610f0e57600080fd5b60018260ff1610158015610f26575060058260ff1611155b1515610f3157600080fd5b837f9f44fa19e0abffa12779e64cc67180970a6d6347762f4ac38fc2138aa91c1c63838360405160ff909216825260208201526040908101905180910390a250505050565b6000610f818261185a565b600381015490915033600160a060020a0390811691161461084857600080fd5b6004600382015460a060020a900460ff166011811115610fbd57fe5b14610fc757600080fd5b8054610cc09083908390600690600160a060020a0316611c11565b600082821115610fee57fe5b50900390565b60038082015460a060020a900460ff16601181111561100f57fe5b1461101957600080fd5b611024816004611f57565b817f8b121cf0b80d0ec0eca560152e8d363b52a2a71555996ab42c92d4085260df2960405160405180910390a25050565b6001600382015460a060020a900460ff16601181111561107157fe5b1461107b57600080fd5b817f4c4e829c9b8c87162e976ab955be6db24dace1afaa0ebe4308b6c273a92f587560405160405180910390a2805460058201546110c291600160a060020a031690611b16565b50610cc082826000611b3b565b6000806004600386015460a060020a900460ff1660118111156110ee57fe5b146110f857600080fd5b600585015461110d858563ffffffff61180716565b1461111757600080fd5b6003850154600160a060020a0316636351546d858560006040516040015260405160e060020a63ffffffff8516028152600481019290925260248201526044016040805180830381600087803b151561116f57600080fd5b6102c65a03f1151561118057600080fd5b5050506040518051906020018051919350909150508382118015906111a55750828111155b15156111b057600080fd5b857f71ee872f6b66015ff808a57b598a99d1ee18238cc1e404131e3819b2ea1c5d67858585856040518085815260200184815260200183815260200182815260200194505050505060405180910390a2845461122490600160a060020a031661121f868563ffffffff610fe216565b611b16565b50600185015461124790600160a060020a031661121f858463ffffffff610fe216565b50600385015461126a90600160a060020a031661121f848463ffffffff61180716565b5061127786866001611b3b565b505050505050565b6000600160a060020a038316151561129657600080fd5b600160a060020a0333166000908152602081905260409020548211156112bb57600080fd5b600160a060020a0333166000908152602081905260409020546112e4908363ffffffff610fe216565b600160a060020a033381166000908152602081905260408082209390935590851681522054611319908363ffffffff61180716565b60008085600160a060020a0316600160a060020a031681526020019081526020016000208190555082600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405190815260200160405180910390a350600192915050565b6001600382015460a060020a900460ff1660118111156113ad57fe5b146113b757600080fd5b6003810154600160a060020a0316156113d5576113d5816002611f57565b817f7a1b26a806da79e562075fc6b7e43c2b23b32be7ee69504c79293740427bdf6c60405160405180910390a26003810154600160a060020a03161515610cc0576001810154610cc09083908390600990600160a060020a0316611c11565b60038082015460a060020a900460ff16601181111561144f57fe5b1461145957600080fd5b61146881610b7b836002611876565b151561147357600080fd5b8054610cc09083908390600e90600160a060020a0316611c11565b60006002600383015460a060020a900460ff1660118111156114ac57fe5b14156114ba57506009611523565b60038083015460a060020a900460ff1660118111156114d557fe5b14156114e35750600c611523565b6004600383015460a060020a900460ff1660118111156114ff57fe5b141561017c5761151482610b7b846003611876565b151561151f57600080fd5b50600f5b60018201546106f390849084908490600160a060020a0316611c11565b60008080600160a060020a0389161580159061156e575033600160a060020a031689600160a060020a031614155b151561157957600080fd5b33600160a060020a031684600160a060020a0316141580156115ad575088600160a060020a031684600160a060020a031614155b15156115b857600080fd5b600088116115c557600080fd5b600160a060020a03851615156115ee57600160a060020a038616156115e957600080fd5b611603565b600160a060020a038616151561160357600080fd5b5050600380546001808201835560008281526004602052604090208054600160a060020a0333811673ffffffffffffffffffffffffffffffffffffffff199283161783558284018054918e1691909216179055928301805492939274ff0000000000000000000000000000000000000000191660a060020a8302179055506005810188905560028101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0388161790556116be82828787611f98565b6116c8828561206a565b88600160a060020a031633600160a060020a0316837f35828c8d6154574f01b22f17b2042aec1f7cb05d62f0301a30265c4dd2da9c23878a8a8e8e604051600160a060020a0395861681529385166020850152919093166040808401919091526060830193909352608082015260a001905180910390a461174a33308a6120fd565b509098975050505050505050565b60006002600383015460a060020a900460ff16601181111561177657fe5b14156117845750600a6117ed565b60038083015460a060020a900460ff16601181111561179f57fe5b14156117ad5750600d6117ed565b6004600383015460a060020a900460ff1660118111156117c957fe5b141561017c576117de82610b7b846003611876565b15156117e957600080fd5b5060105b81546106f390849084908490600160a060020a0316611c11565b60008282018381101561096857fe5b6004600382015460a060020a900460ff16601181111561183257fe5b1461183c57600080fd5b6001810154610cc09083908390600890600160a060020a0316611c11565b6000818152600460205260409020600354821061084857600080fd5b600080808084600381111561188757fe5b1415611907576002850154600160a060020a0316620f42406040517f7472616e73616374696f6e4578706972792829000000000000000000000000008152601301604051809103902060e060020a9004906040518263ffffffff1660e060020a02815260040160006040518083038160008887f193505050509050611aac565b600184600381111561191557fe5b1415611995576002850154600160a060020a0316620f42406040517f66756c66696c6c6d656e744578706972792829000000000000000000000000008152601301604051809103902060e060020a9004906040518263ffffffff1660e060020a02815260040160006040518083038160008887f193505050509050611aac565b60028460038111156119a357fe5b1415611a23576002850154600160a060020a0316620f42406040517f657363616c6174696f6e457870697279282900000000000000000000000000008152601201604051809103902060e060020a9004906040518263ffffffff1660e060020a02815260040160006040518083038160008887f193505050509050611aac565b6003846003811115611a3157fe5b1415611aac576003850154600160a060020a0316620f42406040517f6d6564696174696f6e45787069727928290000000000000000000000000000008152601101604051809103902060e060020a9004906040518263ffffffff1660e060020a02815260040160006040518083038160008887f19450505050505b8015611aca5760203d1415611aca5760405160206000823e80519250505b8192505b505092915050565b60008163ffffffff16611af6846004015442610fe290919063ffffffff16565b10159392505050565b6000808284811515611b0d57fe5b04949350505050565b600080821115611b3257611b2b3084846120fd565b9050610647565b50600192915050565b8015611ba15760038201805460018401805473ffffffffffffffffffffffffffffffffffffffff19908116909155600285018054909116905574ffffffffffffffffffffffffffffffffffffffffff1916905560006004830181905560058301556106f3565b505060009081526004602081905260408220805473ffffffffffffffffffffffffffffffffffffffff19908116825560018201805482169055600282018054909116905560038101805474ffffffffffffffffffffffffffffffffffffffffff1916905590810182905560050155565b6000611c1d84846121f8565b90506009836011811115611c2d57fe5b1415611c6c57847f4b7c1d2c22e04f819aa1ab2f67b789b2432185c9cedbd628e119c1ff7e6f46a58260405190815260200160405180910390a2611f0f565b600c836011811115611c7a57fe5b1415611cb957847f5576af7dc4242c1c01eea6e56373d17ea24ffe9aed53a2d1ef839b67bf4f2c398260405190815260200160405180910390a2611f0f565b600f836011811115611cc757fe5b1415611cff57847f450d94efd29a31cdb09ddbe25c83523a34f947d3259a820ef2ea4fe5813e8d1060405160405180910390a2611f0f565b600b836011811115611d0d57fe5b1415611d4c57847f4ff1ddec585d16be2198539398b5fb2a9ad551e7c49015adccc77770f32eece18260405190815260200160405180910390a2611f0f565b600a836011811115611d5a57fe5b1415611d9957847f7efce4ff22cb1dc0ec2d7360a102d3a72f80f135a3225d1d4b5900bfe01772c78260405190815260200160405180910390a2611f0f565b600d836011811115611da757fe5b1415611de657847fd245a08477e3a73e161b57006daf04802fbdc3a73e83f0a1c88bc7ef24c008dc8260405190815260200160405180910390a2611f0f565b6010836011811115611df457fe5b1415611e2c57847f25107a47cbfbdd273f20e135cb8a301e5d3ec7e57d6c1ade30872c6b7abef83660405160405180910390a2611f0f565b600e836011811115611e3a57fe5b1415611e7957847fdd68b3868d9fe2fb70f4ad224f3b016220ced249fe29f3d6cc40f993a8b1992f8260405190815260200160405180910390a2611f0f565b6006836011811115611e8757fe5b1415611ec657847fd2231919a95e10714ef63773b9983e2a78e27e6c42a1e5702f382f50a81b92218260405190815260200160405180910390a2611f0f565b6008836011811115611ed457fe5b1415611f0f57847f1217b6ffcf46b9b41bf25d22d73fa7b407bbb50bb3601728c80d288e2de5634d8260405190815260200160405180910390a25b611f2a8261121f838760050154610fe290919063ffffffff16565b506003840154611f4390600160a060020a031682611b16565b50611f5085856001611b3b565b5050505050565b60038201805482919074ff0000000000000000000000000000000000000000191660a060020a836011811115611f8957fe5b02179055505042600490910155565b600160a060020a03821615610c315781600160a060020a031663bc3c28468585600501548460006040516020015260405160e060020a63ffffffff861602815260048101939093526024830191909152600160a060020a03166044820152606401602060405180830381600087803b151561201257600080fd5b6102c65a03f1151561202357600080fd5b50505060405180519050151561203857600080fd5b600383018054600160a060020a03841673ffffffffffffffffffffffffffffffffffffffff1990911617905550505050565b600160a060020a03811615610cc05780600160a060020a03166359a23200833360006040516020015260405160e060020a63ffffffff85160281526004810192909252600160a060020a03166024820152604401602060405180830381600087803b15156120d757600080fd5b6102c65a03f115156120e857600080fd5b505050604051805190501515610cc057600080fd5b6000600160a060020a038316151561211457600080fd5b600160a060020a03841660009081526020819052604090205482111561213957600080fd5b600160a060020a038416600090815260208190526040902054612162908363ffffffff610fe216565b600160a060020a038086166000908152602081905260408082209390935590851681522054612197908363ffffffff61180716565b600160a060020a03808516600081815260208190526040908190209390935591908616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060019392505050565b600382015460009081908190600160a060020a0316151561221c5760009250611ace565b600984601181111561222a57fe5b14156122b7576003850154600160a060020a0316623d09006040517f636f6e6669726d5472616e73616374696f6e4665652875696e743235362900008152601e01604051809103902060e060020a900490876005015460405160e060020a63ffffffff8516028152600481019190915260240160006040518083038160008887f193505050509050612773565b600b8460118111156122c557fe5b1415612378576003850154600160a060020a0316623d09006040517f636f6e6669726d5472616e73616374696f6e416674657245787069727946656581527f2875696e743235362900000000000000000000000000000000000000000000006020820152602901604051809103902060e060020a900490876005015460405160e060020a63ffffffff8516028152600481019190915260240160006040518083038160008887f193505050509050612773565b600c84601181111561238657fe5b1415612439576003850154600160a060020a0316623d09006040517f636f6e6669726d5472616e73616374696f6e416674657244697370757465466581527f652875696e7432353629000000000000000000000000000000000000000000006020820152602a01604051809103902060e060020a900490876005015460405160e060020a63ffffffff8516028152600481019190915260240160006040518083038160008887f193505050509050612773565b600884601181111561244757fe5b14156124ca5760038501546005860154600160a060020a039091169063c32049549060006040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156124a857600080fd5b6102c65a03f115156124b957600080fd5b505050604051805190509150612773565b600a8460118111156124d857fe5b1415612565576003850154600160a060020a0316623d09006040517f726566756e645472616e73616374696f6e4665652875696e74323536290000008152601d01604051809103902060e060020a900490876005015460405160e060020a63ffffffff8516028152600481019190915260240160006040518083038160008887f193505050509050612773565b600e84601181111561257357fe5b1415612626576003850154600160a060020a0316623d09006040517f726566756e645472616e73616374696f6e41667465724578706972794665652881527f75696e74323536290000000000000000000000000000000000000000000000006020820152602801604051809103902060e060020a900490876005015460405160e060020a63ffffffff8516028152600481019190915260240160006040518083038160008887f193505050509050612773565b600d84601181111561263457fe5b14156126e7576003850154600160a060020a0316623d09006040517f726566756e645472616e73616374696f6e41667465724469737075746546656581527f2875696e743235362900000000000000000000000000000000000000000000006020820152602901604051809103902060e060020a900490876005015460405160e060020a63ffffffff8516028152600481019190915260240160006040518083038160008887f193505050509050612773565b60068460118111156126f557fe5b14156127735760038501546005860154600160a060020a039091169063dc6e72629060006040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561275657600080fd5b6102c65a03f1151561276757600080fd5b50505060405180519250505b80156127a75760203d14156127915760405160206000823e80519250505b84600501548211156127a257600091505b611aca565b6005850154821115611aca57600080fd00a165627a7a7230582013d61abf9006212fe2597c883702fecfa447c69dc73458762961dd5cdb9db0bb0029
Verified Source Code Partial Match
Compiler: v0.4.19+commit.c4cbbb05
Optimization: Yes (200 runs)
InkProtocol.sol 1215 lines
pragma solidity ^0.4.18;
// File: contracts/InkMediator.sol
interface InkMediator {
function mediationExpiry() external returns (uint32);
function requestMediator(uint256 _transactionId, uint256 _transactionAmount, address _transactionOwner) external returns (bool);
function confirmTransactionFee(uint256 _transactionAmount) external returns (uint256);
function confirmTransactionAfterExpiryFee(uint256 _transactionAmount) external returns (uint256);
function confirmTransactionAfterDisputeFee(uint256 _transactionAmount) external returns (uint256);
function confirmTransactionByMediatorFee(uint256 _transactionAmount) external returns (uint256);
function refundTransactionFee(uint256 _transactionAmount) external returns (uint256);
function refundTransactionAfterExpiryFee(uint256 _transactionAmount) external returns (uint256);
function refundTransactionAfterDisputeFee(uint256 _transactionAmount) external returns (uint256);
function refundTransactionByMediatorFee(uint256 _transactionAmount) external returns (uint256);
function settleTransactionByMediatorFee(uint256 _buyerAmount, uint256 _sellerAmount) external returns (uint256, uint256);
}
// File: contracts/InkOwner.sol
interface InkOwner {
function authorizeTransaction(uint256 _id, address _buyer) external returns (bool);
}
// File: contracts/InkProtocolInterface.sol
interface InkProtocolInterface {
// Event emitted when a transaction is initiated.
event TransactionInitiated(
uint256 indexed id,
address owner,
address indexed buyer,
address indexed seller,
address policy,
address mediator,
uint256 amount,
// A hash string representing the metadata for the transaction. This is
// somewhat arbitrary for the transaction. Only the transaction owner
// will really know the original contents of the metadata and may choose
// to share it at their discretion.
bytes32 metadata
);
// Event emitted when a transaction has been accepted by the seller.
event TransactionAccepted(
uint256 indexed id
);
// Event emitted when a transaction has been disputed by the buyer.
event TransactionDisputed(
uint256 indexed id
);
// Event emitted when a transaction is escalated to the mediator by the
// seller.
event TransactionEscalated(
uint256 indexed id
);
// Event emitted when a transaction is revoked by the seller.
event TransactionRevoked(
uint256 indexed id
);
// Event emitted when a transaction is revoked by the seller.
event TransactionRefundedByMediator(
uint256 indexed id,
uint256 mediatorFee
);
// Event emitted when a transaction is settled by the mediator.
event TransactionSettledByMediator(
uint256 indexed id,
uint256 buyerAmount,
uint256 sellerAmount,
uint256 buyerMediatorFee,
uint256 sellerMediatorFee
);
// Event emitted when a transaction is confirmed by the mediator.
event TransactionConfirmedByMediator(
uint256 indexed id,
uint256 mediatorFee
);
// Event emitted when a transaction is confirmed by the buyer.
event TransactionConfirmed(
uint256 indexed id,
uint256 mediatorFee
);
// Event emitted when a transaction is refunded by the seller.
event TransactionRefunded(
uint256 indexed id,
uint256 mediatorFee
);
// Event emitted when a transaction is confirmed by the seller after the
// transaction expiry.
event TransactionConfirmedAfterExpiry(
uint256 indexed id,
uint256 mediatorFee
);
// Event emitted when a transaction is confirmed by the buyer after it was
// disputed.
event TransactionConfirmedAfterDispute(
uint256 indexed id,
uint256 mediatorFee
);
// Event emitted when a transaction is refunded by the seller after it was
// disputed.
event TransactionRefundedAfterDispute(
uint256 indexed id,
uint256 mediatorFee
);
// Event emitted when a transaction is refunded by the buyer after the
// escalation expiry.
event TransactionRefundedAfterExpiry(
uint256 indexed id,
uint256 mediatorFee
);
// Event emitted when a transaction is confirmed by the buyer after the
// mediation expiry.
event TransactionConfirmedAfterEscalation(
uint256 indexed id
);
// Event emitted when a transaction is refunded by the seller after the
// mediation expiry.
event TransactionRefundedAfterEscalation(
uint256 indexed id
);
// Event emitted when a transaction is settled by either the buyer or the
// seller after the mediation expiry.
event TransactionSettled(
uint256 indexed id,
uint256 buyerAmount,
uint256 sellerAmount
);
// Event emitted when a transaction's feedback is updated by the buyer.
event FeedbackUpdated(
uint256 indexed transactionId,
uint8 rating,
bytes32 comment
);
// Event emitted an account is (unidirectionally) linked to another account.
// For two accounts to be acknowledged as linked, the linkage must be
// bidirectional.
event AccountLinked(
address indexed from,
address indexed to
);
/* Protocol */
function link(address _to) external;
function createTransaction(address _seller, uint256 _amount, bytes32 _metadata, address _policy, address _mediator) external returns (uint256);
function createTransaction(address _seller, uint256 _amount, bytes32 _metadata, address _policy, address _mediator, address _owner) external returns (uint256);
function revokeTransaction(uint256 _id) external;
function acceptTransaction(uint256 _id) external;
function confirmTransaction(uint256 _id) external;
function confirmTransactionAfterExpiry(uint256 _id) external;
function refundTransaction(uint256 _id) external;
function refundTransactionAfterExpiry(uint256 _id) external;
function disputeTransaction(uint256 _id) external;
function escalateDisputeToMediator(uint256 _id) external;
function settleTransaction(uint256 _id) external;
function refundTransactionByMediator(uint256 _id) external;
function confirmTransactionByMediator(uint256 _id) external;
function settleTransactionByMediator(uint256 _id, uint256 _buyerAmount, uint256 _sellerAmount) external;
function provideTransactionFeedback(uint256 _id, uint8 _rating, bytes32 _comment) external;
/* ERC20 */
function totalSupply() public view returns (uint256);
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
function allowance(address owner, address spender) public view returns (uint256);
function increaseApproval(address spender, uint addedValue) public returns (bool);
function decreaseApproval(address spender, uint subtractedValue) public returns (bool);
}
// File: zeppelin-solidity/contracts/math/SafeMath.sol
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
// File: zeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol
/**
* @title ERC20Basic
* @dev Simpler version of ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/179
*/
contract ERC20Basic {
function totalSupply() public view returns (uint256);
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
// File: zeppelin-solidity/contracts/token/ERC20/BasicToken.sol
/**
* @title Basic token
* @dev Basic version of StandardToken, with no allowances.
*/
contract BasicToken is ERC20Basic {
using SafeMath for uint256;
mapping(address => uint256) balances;
uint256 totalSupply_;
/**
* @dev total number of tokens in existence
*/
function totalSupply() public view returns (uint256) {
return totalSupply_;
}
/**
* @dev transfer token for a specified address
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
*/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[msg.sender]);
// SafeMath.sub will throw if there is not enough balance.
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public view returns (uint256 balance) {
return balances[_owner];
}
}
// File: zeppelin-solidity/contracts/token/ERC20/ERC20.sol
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) public view returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// File: zeppelin-solidity/contracts/token/ERC20/StandardToken.sol
/**
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* @dev https://github.com/ethereum/EIPs/issues/20
* @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract StandardToken is ERC20, BasicToken {
mapping (address => mapping (address => uint256)) internal allowed;
/**
* @dev Transfer tokens from one address to another
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
*/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
Transfer(_from, _to, _value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
*
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param _owner address The address which owns the funds.
* @param _spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(address _owner, address _spender) public view returns (uint256) {
return allowed[_owner][_spender];
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
*
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _addedValue The amount of tokens to increase the allowance by.
*/
function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
*
* approve should be called when allowed[_spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _subtractedValue The amount of tokens to decrease the allowance by.
*/
function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
uint oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
}
// File: contracts/InkProtocolCore.sol
/// @title Ink Protocol: Decentralized reputation and payments for peer-to-peer marketplaces.
contract InkProtocolCore is InkProtocolInterface, StandardToken {
string public constant name = "Ink Protocol";
string public constant symbol = "XNK";
uint8 public constant decimals = 18;
uint256 private constant gasLimitForExpiryCall = 1000000;
uint256 private constant gasLimitForMediatorCall = 4000000;
enum Expiry {
Transaction, // 0
Fulfillment, // 1
Escalation, // 2
Mediation // 3
}
enum TransactionState {
// This is an internal state to represent an uninitialized transaction.
Null, // 0
Initiated, // 1
Accepted, // 2
Disputed, // 3
Escalated, // 4
Revoked, // 5
RefundedByMediator, // 6
SettledByMediator, // 7
ConfirmedByMediator, // 8
Confirmed, // 9
Refunded, // 10
ConfirmedAfterExpiry, // 11
ConfirmedAfterDispute, // 12
RefundedAfterDispute, // 13
RefundedAfterExpiry, // 14
ConfirmedAfterEscalation, // 15
RefundedAfterEscalation, // 16
Settled // 17
}
// The running ID counter for all Ink Transactions.
uint256 private globalTransactionId = 0;
// Mapping of all transactions by ID (globalTransactionId).
mapping(uint256 => Transaction) internal transactions;
// The struct definition for an Ink Transaction.
struct Transaction {
// The address of the buyer on the transaction.
address buyer;
// The address of the seller on the transaction.
address seller;
// The address of the policy contract for the transaction.
address policy;
// The address of the mediator contract for the transaction.
address mediator;
// The state of the transaction.
TransactionState state;
// The (block) time that the transaction transitioned to its current state.
// This value is only set for the states that need it to be set (states
// with an expiry involved).
uint256 stateTime;
// The XNK amount of the transaction.
uint256 amount;
}
/*
Constructor
*/
function InkProtocolCore() internal {
// Start with a total supply of 500,000,000 Ink Tokens (XNK).
totalSupply_ = 500000000000000000000000000;
}
/*
ERC20 override functions
*/
function transfer(address _to, uint256 _value) public returns (bool) {
// Don't allow token transfers to the Ink contract.
require(_to != address(this));
return super.transfer(_to, _value);
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
// Don't allow token transfers to the Ink contract.
require(_to != address(this));
return super.transferFrom(_from, _to, _value);
}
/*
Account linking functions
Functions used by users and agents to declare a unidirectionally account
linking.
*/
// Called by a user who wishes to link with another _account.
function link(address _to) external {
require(_to != address(0));
require(_to != msg.sender);
AccountLinked({
from: msg.sender,
to: _to
});
}
/*
Transaction functions
*/
function createTransaction(address _seller, uint256 _amount, bytes32 _metadata, address _policy, address _mediator) external returns (uint256) {
return _createTransaction(_seller, _amount, _metadata, _policy, _mediator, address(0));
}
function createTransaction(address _seller, uint256 _amount, bytes32 _metadata, address _policy, address _mediator, address _owner) external returns (uint256) {
return _createTransaction(_seller, _amount, _metadata, _policy, _mediator, _owner);
}
function revokeTransaction(uint256 _id) external {
_revokeTransaction(_id, _findTransactionForBuyer(_id));
}
function acceptTransaction(uint256 _id) external {
_acceptTransaction(_id, _findTransactionForSeller(_id));
}
function confirmTransaction(uint256 _id) external {
_confirmTransaction(_id, _findTransactionForBuyer(_id));
}
function confirmTransactionAfterExpiry(uint256 _id) external {
_confirmTransactionAfterExpiry(_id, _findTransactionForSeller(_id));
}
function refundTransaction(uint256 _id) external {
_refundTransaction(_id, _findTransactionForSeller(_id));
}
function refundTransactionAfterExpiry(uint256 _id) external {
_refundTransactionAfterExpiry(_id, _findTransactionForBuyer(_id));
}
function disputeTransaction(uint256 _id) external {
_disputeTransaction(_id, _findTransactionForBuyer(_id));
}
function escalateDisputeToMediator(uint256 _id) external {
_escalateDisputeToMediator(_id, _findTransactionForSeller(_id));
}
function settleTransaction(uint256 _id) external {
_settleTransaction(_id, _findTransactionForParty(_id));
}
function refundTransactionByMediator(uint256 _id) external {
_refundTransactionByMediator(_id, _findTransactionForMediator(_id));
}
function confirmTransactionByMediator(uint256 _id) external {
_confirmTransactionByMediator(_id, _findTransactionForMediator(_id));
}
function settleTransactionByMediator(uint256 _id, uint256 _buyerAmount, uint256 _sellerAmount) external {
_settleTransactionByMediator(_id, _findTransactionForMediator(_id), _buyerAmount, _sellerAmount);
}
function provideTransactionFeedback(uint256 _id, uint8 _rating, bytes32 _comment) external {
_provideTransactionFeedback(_id, _findTransactionForBuyer(_id), _rating, _comment);
}
/*
Private functions
*/
function _createTransaction(address _seller, uint256 _amount, bytes32 _metadata, address _policy, address _mediator, address _owner) private returns (uint256) {
require(_seller != address(0) && _seller != msg.sender);
require(_owner != msg.sender && _owner != _seller);
require(_amount > 0);
// Per specifications, if a mediator is involved then a policy is required.
// Otherwise, policy must be a zero address.
if (_mediator == address(0)) {
require(_policy == address(0));
} else {
require(_policy != address(0));
}
// Increment the transaction.
uint256 id = globalTransactionId++;
// Create the transaction.
Transaction storage transaction = transactions[id];
transaction.buyer = msg.sender;
transaction.seller = _seller;
transaction.state = TransactionState.Initiated;
transaction.amount = _amount;
transaction.policy = _policy;
_resolveMediator(id, transaction, _mediator, _owner);
_resolveOwner(id, _owner);
// Emit the event.
TransactionInitiated({
id: id,
owner: _owner,
buyer: msg.sender,
seller: _seller,
policy: _policy,
mediator: _mediator,
amount: _amount,
metadata: _metadata
});
// Place the buyer's tokens in escrow (ie. this contract).
_transferFrom(msg.sender, this, _amount);
// Return the newly created transaction's id.
return id;
}
function _revokeTransaction(uint256 _id, Transaction storage _transaction) private {
require(_transaction.state == TransactionState.Initiated);
TransactionRevoked({ id: _id });
_transferFromEscrow(_transaction.buyer, _transaction.amount);
_cleanupTransaction(_id, _transaction, false);
}
function _acceptTransaction(uint256 _id, Transaction storage _transaction) private {
require(_transaction.state == TransactionState.Initiated);
if (_transaction.mediator != address(0)) {
_updateTransactionState(_transaction, TransactionState.Accepted);
}
TransactionAccepted({ id: _id });
if (_transaction.mediator == address(0)) {
// If there is no mediator involved, the transaction is immediately confirmed.
_completeTransaction(_id, _transaction, TransactionState.Confirmed, _transaction.seller);
}
}
function _confirmTransaction(uint256 _id, Transaction storage _transaction) private {
TransactionState finalState;
if (_transaction.state == TransactionState.Accepted) {
finalState = TransactionState.Confirmed;
} else if (_transaction.state == TransactionState.Disputed) {
finalState = TransactionState.ConfirmedAfterDispute;
} else if (_transaction.state == TransactionState.Escalated) {
require(_afterExpiry(_transaction, _fetchExpiry(_transaction, Expiry.Mediation)));
finalState = TransactionState.ConfirmedAfterEscalation;
} else {
revert();
}
_completeTransaction(_id, _transaction, finalState, _transaction.seller);
}
function _confirmTransactionAfterExpiry(uint256 _id, Transaction storage _transaction) private {
require(_transaction.state == TransactionState.Accepted);
require(_afterExpiry(_transaction, _fetchExpiry(_transaction, Expiry.Transaction)));
_completeTransaction(_id, _transaction, TransactionState.ConfirmedAfterExpiry, _transaction.seller);
}
function _refundTransaction(uint256 _id, Transaction storage _transaction) private {
TransactionState finalState;
if (_transaction.state == TransactionState.Accepted) {
finalState = TransactionState.Refunded;
} else if (_transaction.state == TransactionState.Disputed) {
finalState = TransactionState.RefundedAfterDispute;
} else if (_transaction.state == TransactionState.Escalated) {
require(_afterExpiry(_transaction, _fetchExpiry(_transaction, Expiry.Mediation)));
finalState = TransactionState.RefundedAfterEscalation;
} else {
revert();
}
_completeTransaction(_id, _transaction, finalState, _transaction.buyer);
}
function _refundTransactionAfterExpiry(uint256 _id, Transaction storage _transaction) private {
require(_transaction.state == TransactionState.Disputed);
require(_afterExpiry(_transaction, _fetchExpiry(_transaction, Expiry.Escalation)));
_completeTransaction(_id, _transaction, TransactionState.RefundedAfterExpiry, _transaction.buyer);
}
function _disputeTransaction(uint256 _id, Transaction storage _transaction) private {
require(_transaction.state == TransactionState.Accepted);
require(_afterExpiry(_transaction, _fetchExpiry(_transaction, Expiry.Fulfillment)));
_updateTransactionState(_transaction, TransactionState.Disputed);
TransactionDisputed({ id: _id });
}
function _escalateDisputeToMediator(uint256 _id, Transaction storage _transaction) private {
require(_transaction.state == TransactionState.Disputed);
_updateTransactionState(_transaction, TransactionState.Escalated);
TransactionEscalated({ id: _id });
}
function _settleTransaction(uint256 _id, Transaction storage _transaction) private {
require(_transaction.state == TransactionState.Escalated);
require(_afterExpiry(_transaction, _fetchExpiry(_transaction, Expiry.Mediation)));
// Divide the escrow amount in half and give it to the buyer. There's
// a possibility that one account will get slightly more than the other.
// We have decided to give the lesser amount to the buyer (arbitrarily).
uint256 buyerAmount = _transaction.amount.div(2);
// The remaining amount is given to the seller.
uint256 sellerAmount = _transaction.amount.sub(buyerAmount);
TransactionSettled({
id: _id,
buyerAmount: buyerAmount,
sellerAmount: sellerAmount
});
_transferFromEscrow(_transaction.buyer, buyerAmount);
_transferFromEscrow(_transaction.seller, sellerAmount);
_cleanupTransaction(_id, _transaction, true);
}
function _refundTransactionByMediator(uint256 _id, Transaction storage _transaction) private {
require(_transaction.state == TransactionState.Escalated);
_completeTransaction(_id, _transaction, TransactionState.RefundedByMediator, _transaction.buyer);
}
function _confirmTransactionByMediator(uint256 _id, Transaction storage _transaction) private {
require(_transaction.state == TransactionState.Escalated);
_completeTransaction(_id, _transaction, TransactionState.ConfirmedByMediator, _transaction.seller);
}
function _settleTransactionByMediator(uint256 _id, Transaction storage _transaction, uint256 _buyerAmount, uint256 _sellerAmount) private {
require(_transaction.state == TransactionState.Escalated);
require(_buyerAmount.add(_sellerAmount) == _transaction.amount);
uint256 buyerMediatorFee;
uint256 sellerMediatorFee;
(buyerMediatorFee, sellerMediatorFee) = InkMediator(_transaction.mediator).settleTransactionByMediatorFee(_buyerAmount, _sellerAmount);
// Require that the sum of the fees be no more than the transaction's amount.
require(buyerMediatorFee <= _buyerAmount && sellerMediatorFee <= _sellerAmount);
TransactionSettledByMediator({
id: _id,
buyerAmount: _buyerAmount,
sellerAmount: _sellerAmount,
buyerMediatorFee: buyerMediatorFee,
sellerMediatorFee: sellerMediatorFee
});
_transferFromEscrow(_transaction.buyer, _buyerAmount.sub(buyerMediatorFee));
_transferFromEscrow(_transaction.seller, _sellerAmount.sub(sellerMediatorFee));
_transferFromEscrow(_transaction.mediator, buyerMediatorFee.add(sellerMediatorFee));
_cleanupTransaction(_id, _transaction, true);
}
function _provideTransactionFeedback(uint256 _id, Transaction storage _transaction, uint8 _rating, bytes32 _comment) private {
// The transaction must be completed (Null state with a buyer) to allow
// feedback.
require(_transaction.state == TransactionState.Null);
// As per functional specifications, ratings must be an integer between
// 1 and 5, inclusive.
require(_rating >= 1 && _rating <= 5);
FeedbackUpdated({
transactionId: _id,
rating: _rating,
comment: _comment
});
}
function _completeTransaction(uint256 _id, Transaction storage _transaction, TransactionState _finalState, address _transferTo) private {
uint256 mediatorFee = _fetchMediatorFee(_transaction, _finalState);
if (_finalState == TransactionState.Confirmed) {
TransactionConfirmed({ id: _id, mediatorFee: mediatorFee });
} else if (_finalState == TransactionState.ConfirmedAfterDispute) {
TransactionConfirmedAfterDispute({ id: _id, mediatorFee: mediatorFee });
} else if (_finalState == TransactionState.ConfirmedAfterEscalation) {
TransactionConfirmedAfterEscalation({ id: _id });
} else if (_finalState == TransactionState.ConfirmedAfterExpiry) {
TransactionConfirmedAfterExpiry({ id: _id, mediatorFee: mediatorFee });
} else if (_finalState == TransactionState.Refunded) {
TransactionRefunded({ id: _id, mediatorFee: mediatorFee });
} else if (_finalState == TransactionState.RefundedAfterDispute) {
TransactionRefundedAfterDispute({ id: _id, mediatorFee: mediatorFee });
} else if (_finalState == TransactionState.RefundedAfterEscalation) {
TransactionRefundedAfterEscalation({ id: _id });
} else if (_finalState == TransactionState.RefundedAfterExpiry) {
TransactionRefundedAfterExpiry({ id: _id, mediatorFee: mediatorFee });
} else if (_finalState == TransactionState.RefundedByMediator) {
TransactionRefundedByMediator({ id: _id, mediatorFee: mediatorFee });
} else if (_finalState == TransactionState.ConfirmedByMediator) {
TransactionConfirmedByMediator({ id: _id, mediatorFee: mediatorFee });
}
_transferFromEscrow(_transferTo, _transaction.amount.sub(mediatorFee));
_transferFromEscrow(_transaction.mediator, mediatorFee);
_cleanupTransaction(_id, _transaction, true);
}
function _fetchExpiry(Transaction storage _transaction, Expiry _expiryType) private returns (uint32) {
uint32 expiry;
bool success;
if (_expiryType == Expiry.Transaction) {
success = _transaction.policy.call.gas(gasLimitForExpiryCall)(bytes4(keccak256("transactionExpiry()")));
} else if (_expiryType == Expiry.Fulfillment) {
success = _transaction.policy.call.gas(gasLimitForExpiryCall)(bytes4(keccak256("fulfillmentExpiry()")));
} else if (_expiryType == Expiry.Escalation) {
success = _transaction.policy.call.gas(gasLimitForExpiryCall)(bytes4(keccak256("escalationExpiry()")));
} else if (_expiryType == Expiry.Mediation) {
success = _transaction.mediator.call.gas(gasLimitForExpiryCall)(bytes4(keccak256("mediationExpiry()")));
}
if (success) {
assembly {
if eq(returndatasize(), 0x20) {
let _freeMemPointer := mload(0x40)
returndatacopy(_freeMemPointer, 0, 0x20)
expiry := mload(_freeMemPointer)
}
}
}
return expiry;
}
function _fetchMediatorFee(Transaction storage _transaction, TransactionState _finalState) private returns (uint256) {
if (_transaction.mediator == address(0)) {
return 0;
}
uint256 mediatorFee;
bool success;
if (_finalState == TransactionState.Confirmed) {
success = _transaction.mediator.call.gas(gasLimitForMediatorCall)(bytes4(keccak256("confirmTransactionFee(uint256)")), _transaction.amount);
} else if (_finalState == TransactionState.ConfirmedAfterExpiry) {
success = _transaction.mediator.call.gas(gasLimitForMediatorCall)(bytes4(keccak256("confirmTransactionAfterExpiryFee(uint256)")), _transaction.amount);
} else if (_finalState == TransactionState.ConfirmedAfterDispute) {
success = _transaction.mediator.call.gas(gasLimitForMediatorCall)(bytes4(keccak256("confirmTransactionAfterDisputeFee(uint256)")), _transaction.amount);
} else if (_finalState == TransactionState.ConfirmedByMediator) {
mediatorFee = InkMediator(_transaction.mediator).confirmTransactionByMediatorFee(_transaction.amount);
} else if (_finalState == TransactionState.Refunded) {
success = _transaction.mediator.call.gas(gasLimitForMediatorCall)(bytes4(keccak256("refundTransactionFee(uint256)")), _transaction.amount);
} else if (_finalState == TransactionState.RefundedAfterExpiry) {
success = _transaction.mediator.call.gas(gasLimitForMediatorCall)(bytes4(keccak256("refundTransactionAfterExpiryFee(uint256)")), _transaction.amount);
} else if (_finalState == TransactionState.RefundedAfterDispute) {
success = _transaction.mediator.call.gas(gasLimitForMediatorCall)(bytes4(keccak256("refundTransactionAfterDisputeFee(uint256)")), _transaction.amount);
} else if (_finalState == TransactionState.RefundedByMediator) {
mediatorFee = InkMediator(_transaction.mediator).refundTransactionByMediatorFee(_transaction.amount);
}
if (success) {
assembly {
if eq(returndatasize(), 0x20) {
let _freeMemPointer := mload(0x40)
returndatacopy(_freeMemPointer, 0, 0x20)
mediatorFee := mload(_freeMemPointer)
}
}
// The mediator's fee cannot be more than transaction's amount.
if (mediatorFee > _transaction.amount) {
mediatorFee = 0;
}
} else {
require(mediatorFee <= _transaction.amount);
}
return mediatorFee;
}
function _resolveOwner(uint256 _transactionId, address _owner) private {
if (_owner != address(0)) {
// If an owner is specified, it must authorize the transaction.
require(InkOwner(_owner).authorizeTransaction(
_transactionId,
msg.sender
));
}
}
function _resolveMediator(uint256 _transactionId, Transaction storage _transaction, address _mediator, address _owner) private {
if (_mediator != address(0)) {
// The mediator must accept the transaction otherwise we abort.
require(InkMediator(_mediator).requestMediator(_transactionId, _transaction.amount, _owner));
// Assign the mediator to the transaction.
_transaction.mediator = _mediator;
}
}
function _afterExpiry(Transaction storage _transaction, uint32 _expiry) private view returns (bool) {
return now.sub(_transaction.stateTime) >= _expiry;
}
function _findTransactionForBuyer(uint256 _id) private view returns (Transaction storage transaction) {
transaction = _findTransaction(_id);
require(msg.sender == transaction.buyer);
}
function _findTransactionForSeller(uint256 _id) private view returns (Transaction storage transaction) {
transaction = _findTransaction(_id);
require(msg.sender == transaction.seller);
}
function _findTransactionForParty(uint256 _id) private view returns (Transaction storage transaction) {
transaction = _findTransaction(_id);
require(msg.sender == transaction.buyer || msg.sender == transaction.seller);
}
function _findTransactionForMediator(uint256 _id) private view returns (Transaction storage transaction) {
transaction = _findTransaction(_id);
require(msg.sender == transaction.mediator);
}
function _findTransaction(uint256 _id) private view returns (Transaction storage transaction) {
transaction = transactions[_id];
require(_id < globalTransactionId);
}
function _transferFrom(address _from, address _to, uint256 _value) private returns (bool) {
require(_to != address(0));
require(_value <= balances[_from]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
Transfer(_from, _to, _value);
return true;
}
function _transferFromEscrow(address _to, uint256 _value) private returns (bool) {
if (_value > 0) {
return _transferFrom(this, _to, _value);
}
return true;
}
function _updateTransactionState(Transaction storage _transaction, TransactionState _state) private {
_transaction.state = _state;
_transaction.stateTime = now;
}
function _cleanupTransaction(uint256 _id, Transaction storage _transaction, bool _completed) private {
// Remove data that is no longer needed on the contract.
if (_completed) {
delete _transaction.state;
delete _transaction.seller;
delete _transaction.policy;
delete _transaction.mediator;
delete _transaction.stateTime;
delete _transaction.amount;
} else {
delete transactions[_id];
}
}
}
// File: zeppelin-solidity/contracts/ownership/Ownable.sol
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
// File: zeppelin-solidity/contracts/token/ERC20/SafeERC20.sol
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure.
* To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
function safeTransfer(ERC20Basic token, address to, uint256 value) internal {
assert(token.transfer(to, value));
}
function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal {
assert(token.transferFrom(from, to, value));
}
function safeApprove(ERC20 token, address spender, uint256 value) internal {
assert(token.approve(spender, value));
}
}
// File: zeppelin-solidity/contracts/token/ERC20/TokenVesting.sol
/**
* @title TokenVesting
* @dev A token holder contract that can release its token balance gradually like a
* typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
* owner.
*/
contract TokenVesting is Ownable {
using SafeMath for uint256;
using SafeERC20 for ERC20Basic;
event Released(uint256 amount);
event Revoked();
// beneficiary of tokens after they are released
address public beneficiary;
uint256 public cliff;
uint256 public start;
uint256 public duration;
bool public revocable;
mapping (address => uint256) public released;
mapping (address => bool) public revoked;
/**
* @dev Creates a vesting contract that vests its balance of any ERC20 token to the
* _beneficiary, gradually in a linear fashion until _start + _duration. By then all
* of the balance will have vested.
* @param _beneficiary address of the beneficiary to whom vested tokens are transferred
* @param _cliff duration in seconds of the cliff in which tokens will begin to vest
* @param _duration duration in seconds of the period in which the tokens will vest
* @param _revocable whether the vesting is revocable or not
*/
function TokenVesting(address _beneficiary, uint256 _start, uint256 _cliff, uint256 _duration, bool _revocable) public {
require(_beneficiary != address(0));
require(_cliff <= _duration);
beneficiary = _beneficiary;
revocable = _revocable;
duration = _duration;
cliff = _start.add(_cliff);
start = _start;
}
/**
* @notice Transfers vested tokens to beneficiary.
* @param token ERC20 token which is being vested
*/
function release(ERC20Basic token) public {
uint256 unreleased = releasableAmount(token);
require(unreleased > 0);
released[token] = released[token].add(unreleased);
token.safeTransfer(beneficiary, unreleased);
Released(unreleased);
}
/**
* @notice Allows the owner to revoke the vesting. Tokens already vested
* remain in the contract, the rest are returned to the owner.
* @param token ERC20 token which is being vested
*/
function revoke(ERC20Basic token) public onlyOwner {
require(revocable);
require(!revoked[token]);
uint256 balance = token.balanceOf(this);
uint256 unreleased = releasableAmount(token);
uint256 refund = balance.sub(unreleased);
revoked[token] = true;
token.safeTransfer(owner, refund);
Revoked();
}
/**
* @dev Calculates the amount that has already vested but hasn't been released yet.
* @param token ERC20 token which is being vested
*/
function releasableAmount(ERC20Basic token) public view returns (uint256) {
return vestedAmount(token).sub(released[token]);
}
/**
* @dev Calculates the amount that has already vested.
* @param token ERC20 token which is being vested
*/
function vestedAmount(ERC20Basic token) public view returns (uint256) {
uint256 currentBalance = token.balanceOf(this);
uint256 totalBalance = currentBalance.add(released[token]);
if (now < cliff) {
return 0;
} else if (now >= start.add(duration) || revoked[token]) {
return totalBalance;
} else {
return totalBalance.mul(now.sub(start)).div(duration);
}
}
}
// File: contracts/InkProtocol.sol
/// @title Ink Protocol: Decentralized reputation and payments for peer-to-peer marketplaces.
contract InkProtocol is InkProtocolCore {
// Allocation addresses.
address public constant __address0__ = 0xA13febeEde2B2924Ce8b27c1512874D3576fEC16;
address public constant __address1__ = 0xc5bA7157b5B69B0fAe9332F30719Eecd79649486;
address public constant __address2__ = 0x29a4b44364A8Bcb6e4d9dd60c222cCaca286ebf2;
address public constant __address3__ = 0xc1DC1e5C3970E22201C5DAB0841abB2DD6499D3F;
address public constant __address4__ = 0x0746d0b67BED258d94D06b15859df8dbd990eC3D;
/*
Constructor for Mainnet.
*/
function InkProtocol() public {
// Unsold tokens due to token sale hard cap.
balances[__address0__] = 19625973697895500000000000;
Transfer(address(0), __address0__, balanceOf(__address0__));
// Allocate 32% to contract for distribution.
// Vesting starts Feb 28, 2018 @ 00:00:00 GMT
TokenVesting vesting1 = new TokenVesting(__address1__, 1519776000, 0, 3 years, false);
balances[vesting1] = 160000000000000000000000000;
Transfer(address(0), vesting1, balanceOf(vesting1));
// Allocate 32% to contract for Listia Inc.
// Vesting starts Feb 28, 2018 @ 00:00:00 GMT
TokenVesting vesting2 = new TokenVesting(__address2__, 1519776000, 0, 3 years, false);
balances[vesting2] = 160000000000000000000000000;
Transfer(address(0), vesting2, balanceOf(vesting2));
// Allocate 6% to wallet for Listia Marketplace credit conversion.
balances[__address3__] = 30000000000000000000000000;
Transfer(address(0), __address3__, balanceOf(__address3__));
// Allocate to wallet for token sale distribution.
balances[__address4__] = 130374026302104500000000000;
Transfer(address(0), __address4__, balanceOf(__address4__));
}
}
Read Contract
__address0__ 0x5a30b194 → address
__address1__ 0xd8ec696f → address
__address2__ 0x10bd6d2b → address
__address3__ 0xf1bd5978 → address
__address4__ 0x7453a417 → address
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
decimals 0x313ce567 → uint8
name 0x06fdde03 → string
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256
Write Contract 21 functions
These functions modify contract state and require a wallet transaction to execute.
acceptTransaction 0xa9dd6895
uint256 _id
approve 0x095ea7b3
address _spender
uint256 _value
returns: bool
confirmTransaction 0xc01a8c84
uint256 _id
confirmTransactionAfterExpiry 0x1f4a5c32
uint256 _id
confirmTransactionByMediator 0xfb0b6b6d
uint256 _id
createTransaction 0xcc94d923
address _seller
uint256 _amount
bytes32 _metadata
address _policy
address _mediator
address _owner
returns: uint256
createTransaction 0xfb8a5f1c
address _seller
uint256 _amount
bytes32 _metadata
address _policy
address _mediator
returns: uint256
decreaseApproval 0x66188463
address _spender
uint256 _subtractedValue
returns: bool
disputeTransaction 0x49bf2caf
uint256 _id
escalateDisputeToMediator 0x6875c319
uint256 _id
increaseApproval 0xd73dd623
address _spender
uint256 _addedValue
returns: bool
link 0x91a89712
address _to
provideTransactionFeedback 0x4f438a12
uint256 _id
uint8 _rating
bytes32 _comment
refundTransaction 0xd4e678b8
uint256 _id
refundTransactionAfterExpiry 0xbfd3c5fa
uint256 _id
refundTransactionByMediator 0x6381ca26
uint256 _id
revokeTransaction 0x735631ad
uint256 _id
settleTransaction 0x19062b8f
uint256 _id
settleTransactionByMediator 0x935e97c2
uint256 _id
uint256 _buyerAmount
uint256 _sellerAmount
transfer 0xa9059cbb
address _to
uint256 _value
returns: bool
transferFrom 0x23b872dd
address _from
address _to
uint256 _value
returns: bool
Recent Transactions
No transactions found for this address